ReviewOS

stacks/analyticshq

[views] The 5 app/auth pages have no layout — they hand-write an stx-layout meta instead

#35
Closed glennmichael123 opened this 9 days ago ·
9 days ago

resources/layouts/ contains exactly one file:

$ ls resources/layouts/
marketing.stx

The 27 marketing pages were migrated onto it (@extends/@section). The five app/auth pages were not. Instead each hand-writes a layout hint:

$ grep -rln 'name="stx-layout"' resources/views/
resources/views/login.stx        # line 61: <meta name="stx-layout" content="auth">
resources/views/dashboard.stx
resources/views/account.stx
resources/views/register.stx
resources/views/sites/new.stx

Consequences

Certain: a 23-line :root{...} design-token block is copy-pasted into all five, and the shared chrome has no single owner. Four raw href="/" anchors on those pages were never converted for the same reason.

Reported but NOT reproduced — needs measuring before you trust it: that the server advertises layout group default for these pages while the client-side getCurrentLayoutGroup() reads the hand-written meta as auth/app, so the router sees a layout change on every in-app navigation, discards the fetched fragment and re-fetches the whole page — a wasted fragment fetch plus a full load on all 11 in-app links. I could not reproduce this: the dev server was down when I tried, and a later attempt found no X-STX-Layout-Group header on any route. Measure it before citing it as the reason.

Fix

Add resources/layouts/app.stx and resources/layouts/auth.stx, move the shared chrome and the :root block into them, and replace the five hand-written metas with @extends.

If the double-fetch behaviour is real, these navigations are going down the full-document swap path, which has no runtime/store handoff guard — see stacksjs/stx#1839.

9 days ago

Shipped in c5a26dc.

The auth half was already done — login, register, forgot-password and reset-password all use @extends('auth'). What remained was dashboard.stx and account.stx, which each carried <meta name="stx-layout" content="app"> while no app layout existed on disk.

That meta is the output of layout resolution, not an input: stx emits it from the <!-- stx-layout: … --> marker only after a layout resolves, and deriveLayoutGroup takes the group from the layout's filename. Writing it by hand produced the correct header while the mechanism behind it never ran, so the two pages shared no chrome, no styles and no stacks.

Both now @extends('app') against a new resources/layouts/app.stx, built to the shape auth.stx already used (stx-standards §3.4, §3.7):

  • The :root token block, body and .wordmark were duplicated byte-for-byte in both pages and now live once in the layout.
  • Each page had its own <main>; the layout owns the single router container (§3.5), and pages yield a <div> with the classes they already had.
  • Page-local <style> and the pre-paint bootstraps moved to @push('styles')/@push('scripts') — under a layout, stx sweeps orphan blocks into the body after the content (§3.6).

Verified on served output: stx-layout-group now reports three distinct groups (marketing / auth / app) where two surfaces previously reported the same one, all styles land in <head>, exactly one <main> per page, and rendered body text is byte-identical before and after.

Also removed the empty tracked resources/views/components/ directory (§3.3) — everything under views/ is a route, which is why dist/ published components/site-nav.html and listed it in the sitemap.

Sign in to comment on this issue.