Skip to content

fix(serve): honour the configured base path locally - #1

Open
burinc wants to merge 3 commits into
jlt-commons:mainfrom
b12n-oss:main
Open

fix(serve): honour the configured base path locally#1
burinc wants to merge 3 commits into
jlt-commons:mainfrom
b12n-oss:main

Conversation

@burinc

@burinc burinc commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

generate! bakes :base-path into every emitted URL, but serve! was a plain static handler rooted at output-dir that knew nothing about it. A project with a base path therefore previewed as an unstyled page with every link dead: the homepage resolved at /, while the CSS and every nav link it pointed at 404'd under the prefix.

The README already documented this, with a manual workaround:

One caveat on bb serve: it serves the build at the server's root, so a site with a :base-path will 404 its own assets locally while working perfectly once deployed. To check a base-pathed site properly, copy the build into a directory named after the base path and serve its parent.

This makes the workaround unnecessary and removes the caveat.

What changed

serve! normalizes :base-path through the existing base-path fn and passes it to make-static-handler, which strips that prefix from each request before resolving against output-dir, treating the bare base path as the homepage. An empty base path is a no-op, so root-hosted projects are unaffected. The startup line now prints the full URL including the prefix.

Measured against a real project

Before, on a project configured with :base-path "/mcp-tkx":

/                          200
/mcp-tkx/guide/index.html  404   <- what the homepage links to
/mcp-tkx/css/screen.css    404   <- what the homepage loads

After:

/mcp-tkx/                          200
/mcp-tkx/guide/index.html          200
/mcp-tkx/css/screen.css            200
/mcp-tkx/guide/architecture.html   200

raygui-jlt previews the same broken way on main today, for the same reason.

Tests

Two added, covering both directions, because fixing one configuration by breaking the other is the obvious risk here:

  • static-handler-serves-under-the-configured-base-path: a prefixed request resolves, the bare base path serves the homepage, and the unprefixed path is not found.
  • static-handler-is-unaffected-when-root-hosted: with an empty base path, /index.html and / still serve.

Suite goes from 67 tests / 147 assertions to 69 / 152, 0 failures.

burinc added 3 commits August 29, 2026 23:26
generate! bakes :base-path into every emitted URL, but serve! was a
plain static handler rooted at output-dir. A project with a base path
therefore previewed as an unstyled page with every link dead: the
homepage resolved at /, while the CSS and every nav link it pointed at
404'd under the prefix.

serve! now strips the base path before resolving against output-dir, so
local preview matches what deploys. Root-hosted projects, where the base
path is the empty string, are unaffected.
The README told readers that bb serve ignores :base-path and that a
base-pathed site would 404 its own assets locally, with a manual
workaround: copy the build into a directory named after the base path
and serve its parent.

serve! now mounts the build at the configured base path, so the
workaround is unnecessary and the caveat is no longer true.
strip-base-path requires uri to be exactly base, or base followed by
"/". That was the only branch of the cond with no test, and the
docstring's claim about siblings rested on it.

The input matters more than it looks. Most near-misses are masked by the
(subs rel 1) on the next line, which assumes a leading slash: "/x-other"
strips to "-other", loses its first character, and 404s under a broken
guard too, so it discriminates nothing. "/x_index.html" is the shape
that leaks: it strips to "_index.html", the subs drops the underscore,
and the handler serves the real homepage at a uri that is not under the
base path at all.

Verified by breaking the guard: the test fails with 200 where 404 was
expected, and passes again once restored.
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.

1 participant