ReviewOS

stacks/stx

fix: SPA router doesn't swap nav/layout when navigating between different layouts

#1667
Closed glennmichael123 opened this 11 days ago ·
11 days ago

Problem

When navigating between pages that use different layouts (e.g. layouts/app → layouts/coach), the SPA router does a fragment swap of the <main> content but keeps the old layout's nav, sidebar, and other layout-level elements. The user sees the new page content but with the wrong navigation.

Reproduction

  1. Page A extends layouts/app (includes nav.stx with athlete routes)
  2. Page B extends layouts/coach (includes coach-nav.stx with coach routes + coach-sidebar.stx)
  3. Navigate from Page A to Page B via <StxLink to="/coaches">
  4. Expected: Full layout swap — coach nav, coach sidebar, coach content
  5. Actual: Only the <main> content swaps. The athlete nav stays, coach sidebar never appears

Root Cause

The router's layout check ([router] layout check: current=layouts/coach(app) new=layouts/coach(app)) appears to match layouts incorrectly, treating different layouts as the same. When layouts differ, the router should do a full page reload (or full DOM swap) instead of a fragment-only swap.

Current Workaround

Using plain <a href> instead of <StxLink> for cross-layout navigation forces a full page load, which correctly loads the new layout. This works but defeats SPA navigation benefits.

Expected Behavior

When <StxLink> navigates to a page with a different @extends('layouts/...'), the router should:

  1. Detect the layout mismatch
  2. Either do a full page reload OR swap the entire document shell (nav + sidebar + main), not just the <main> fragment

Environment

  • stx version: 0.2.10 (local linked)
  • Two layouts: layouts/app (athlete) and layouts/coach (coach)
  • Training dashboard app with role-based views

🤖 Generated with Claude Code

10 days ago

Fixed on main. checkLayoutChange in packages/router/src/client.ts:172-190 now distinguishes both cases:

  • Different layout group (e.g. auth → app): full page reload (line 181)
  • Same group, different specific layout (e.g. layouts/app → layouts/coach): full body swap (line 187)

The server sets X-STX-Layout / X-STX-Layout-Group headers (production-server.ts:253, dev-server/serve-app.ts:667) and the matching <meta name="stx-layout"> / <meta name="stx-layout-group"> tags in the page head (process.ts:343). The client reads both and picks the right swap strategy, so navigating from an athlete page to a coach page now correctly replaces nav + sidebar.

Sign in to comment on this issue.