ReviewOS

also looking at this

stacks/stx

feat(layouts): honour a fallback layouts directory

#1942
Merged chris wants to merge fix/fallback-layouts-dir into main
5 files +174 -10
8 days ago

A framework that ships default layouts and lets an app override them by name had no way to express that. layoutsDir is a single directory, so an app that defines one layout of its own has to vendor every other layout it uses.

The failure when it does not is the worst kind. A page whose layout does not resolve renders its sections into nothing, so the server returns 200 with an empty body — not a 404, not an error page. Stacks shipped an entire staff dashboard to production that way: every /dashboard/* URL answered 200 with 1398 bytes and no content, because those pages extend the framework's layouts/default while the app's own layouts directory holds only its marketing layout.

What this adds

fallbackLayoutsDir, checked after layoutsDir — an app that defines a layout of the same name still wins, since overriding is the point of shipping defaults.

Two things it needed beyond the lookup itself, both found by testing rather than reading:

  • The resolver's path guard now trusts fallbackLayoutsDir the way it already trusts layoutsDir. A fallback legitimately points outside cwd — a framework's node_modules/.../resources/layouts is the normal case — and without this the guard rejected every hit as an escape. The lookup would have been dead code; the first two tests failed exactly this way.
  • "Layout not found" lists both directories. Naming only the app's own layouts made a resolvable-but-unconfigured fallback look like the layout did not exist anywhere, which sends the search in the wrong direction. That is how the production case above stayed misdiagnosed.

bun-plugin-stx threads the option through all three render paths. Stacks has been passing fallbackLayoutsDir to it since its views server was written — until now nothing read it.

Tests

5 new: the fallback resolves, the app still wins for a name it defines, nested names (layouts/dashboard/default) work, both-missing stays null, and no-fallback behaves exactly as before.

Suite goes from 13 pre-existing failures to 11 — no regressions, and none of the remaining failures touch layout resolution.

5 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.