MoonshotAI / MoonshotAI/kimi-code

Support serving the web UI under a reverse-proxy subpath (iframe embedding)

Open
#1,387 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

What feature would you like to see?

Make the built web UI servable under a reverse-proxy path prefix (subpath), so kimi web can be embedded in an iframe mounted at a non-root path (e.g. https://host/some/prefix/…).

Today the SPA assumes it is served from the origin root, which breaks under a prefix in three ways:

  1. Assets 404index.html and chunks reference /assets/… (absolute). Behind a prefix the browser requests https://host/assets/…, which the proxy doesn't route to the daemon.
  2. REST/WS miss the prefix — the SPA builds API/WS URLs from window.location.origin (apps/kimi-web/src/api/config.ts), so calls go to /api/v1/… without the prefix and never reach the daemon.
  3. Deep-link routing — session routing reads/writes location.pathname at the origin root, so /sessions/<id> isn't recognised under a prefix.

Proposed approach (small, direct-serve-safe):

  1. apps/kimi-web/vite.config.tsbase: './' (relative asset URLs).
  2. apps/kimi-web/index.html — a static <base href="/"> (+ relative favicon) so a direct-serve deep-link hard-refresh still resolves ./assets/* to /assets/*; an embedder injects its own <base href="<prefix>/"> earlier in <head>, and the first <base href> wins, so the prefix takes precedence in-frame.
  3. apps/kimi-web/src/api/config.ts — resolve the server base from document.baseURI instead of location.origin, so REST + WS URLs carry the prefix. At direct-serve document.baseURI === origin + '/', i.e. behavior is unchanged.

No effect on the normal same-origin serve; direct-serve deep-link refresh stays correct via the static <base href="/">.

Additional information

Reproduce: serve the built dist-web behind any path-prefix reverse proxy (or a same-origin iframe mounted at a subpath) → blank frame; the console shows /assets/* 404s followed by /api/v1/* 404s.

Out of scope for this SPA change: a cross-origin embedder must still authorize the browser Origin for the daemon's WebSocket/POST same-origin checks — that's an embedder-side concern (the proxy strips/rewrites Origin, or the daemon is launched with a CORS allowlist), not part of the SPA changes above.

I have a branch ready (~26 lines across the 3 files), verified end-to-end in a headless-browser iframe harness (assets load, REST + WS connect, session deep-link honored, zero console errors). Happy to open a PR if the direction looks good — following the "discuss first" guidance, waiting for maintainer feedback before sending it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/kimi-web/vite.config.ts, index.html, and src/api/config.ts, then inspect the SPA's session routing and run the existing build. Verify that assets, REST and WebSocket requests, and session deep links work under a reverse-proxy path prefix while direct root serving remains unchanged; the issue reports a headless-browser iframe harness for end-to-end validation.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vite
Domain
api, frontend, web-dev
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.