Skip to content

web: mount the app under MOUSEHOLE_BASE_PATH - #191

Open
dlrobson wants to merge 1 commit into
t-mart:masterfrom
dlrobson:subpath-baked-in
Open

dlrobson wants to merge 1 commit into
t-mart:masterfrom
dlrobson:subpath-baked-in

Conversation

@dlrobson

Copy link
Copy Markdown

MOUSEHOLE_BASE_PATH mounts the whole app. UI, API, healthcheck under a URL prefix like /mousehole, so it can share a hostname with another app. Defaults to "" (the origin root, unchanged).

Serving Mousehole alongside another app on one hostname meant either
rebuilding the image per deployment or rewriting paths at the proxy.
MOUSEHOLE_BASE_PATH mounts the whole app — UI, API, healthcheck — under a
prefix such as /mousehole, defaulting to "" (the origin root, unchanged).
docs/hosting-under-a-subpath.md covers the proxy setups.

The value is a path and never a scheme or host, and it is validated once at
startup (base-path.ts), so the worst a bad value can do is refuse to start
with a message naming the variable. A deployment is mounted by
Hono#basePath, which makes the mount a property of the app rather than a
wrapper each registration has to remember: no route template below names
the prefix, and `strict: false` makes a trailing slash insignificant there.
The same prefix is what replies carry — the root redirect's target, the
session cookie's Path (set and cleared from one place in the store), and
the shell's <base>.

The bundle can no longer assume it lives at the origin root, so it is built
with relative asset URLs and the server writes `<prefix>/web/` into the
document's <base> when it serves the shell. That is what makes the UI's own
asset and API URLs resolve under the mount: the frontend derives them from
document.baseURI instead of hardcoding origin-absolute paths, and the
placeholder and default base live in src/shared/ so the Bun server and the
Vite dev server cannot disagree about them. Assembly fails if the shell has
lost its placeholder, since a markerless build would serve base-less HTML
whose relative URLs resolve nowhere.

The healthcheck reads the same variable at run time, so a prefixed container
is not reported unhealthy for serving at the prefix.
@t-mart

t-mart commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR! I'll give it a thorough look next week, things are a bit hectic IRL right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants