fix(router-core): dehydrate all manifest routes so client-side navigations restore shared-chunk CSS - #8225
fix(router-core): dehydrate all manifest routes so client-side navigations restore shared-chunk CSS#8225breken-ai wants to merge 3 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughSSR manifest dehydration now includes assets for all routes. Matched routes still remove inlined CSS entries and emit placeholders. Unmatched routes retain their CSS and preload entries for later client-side navigation. ChangesSSR Manifest Dehydration
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to SSR dehydration now retains route assets needed for later client navigation while preserving inline-CSS behavior for rendered routes. The covered manifest behavior is ready to merge. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Description checkExplanation The description provides a detailed summary, root cause, fix, test plan, regression coverage, and validation results. It does not use the template headings or include the checklist and release-impact sections, but the required change context is substantially complete. Full details: Linked Issues checkExplanation The implementation satisfies issue
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Fixes #8224 - on the first client-side navigation away from the SSR'd entry route, a route whose component shares a chunk with an already-loaded route loses all of its CSS, and the stylesheet is never restored.
Root cause:
dehydrate()inpackages/router-core/src/ssr/ssr-server.tsserialized only the SSR-matched routes into the dehydrated manifest, while the render-timerouter.ssr.manifestgetter exposes all routes. On the client,HeadContentremoves the outgoing route's stylesheet links on navigation and looks the incoming route'scssup in the dehydrated manifest. With the incoming route's entry pruned, nothing re-declares the stylesheet, and Vite won't re-inject it because the chunk's JS module is already in the browser's module cache. The page renders unstyled until a hard refresh.Fix:
dehydrate()now dehydrates all routes, consistent with the render-time getter:inlineCssoff:manifest.routes(every route, untouched)inlineCsson:{ ...manifest.routes, ...preparedManifest.routes }- matched routes keep their stripped entries (their inlined styles are already in the page); unmatched routes dehydrate as-is soHeadContentcan re-declare their assets on client-side navigationMinimal reproduction: https://github.com/breken-ai/tanstack-router-8224-repro (React 18.3.1 - React 19's stylesheet hoisting masks the bug). Load
/, client-navigate to/pool/123: the shared chunk's stylesheet link is removed from<head>and the page loses all styles. With this patch applied, the styles survive navigation.Test plan
tests/issue-8224-dehydrated-manifest-all-routes.test.ts(2 tests) asserting the dehydrated manifest contains every route's assets. Both fail on the unfixed code and pass with the fix (negative control verified).tests/ssr-server-manifest.test.tsencoded the pruning as intended behavior and were updated to the new contract (renames included):omits unmatched route assets by default->dehydrates assets for all routes, not just the SSR matchesomits descendant assets past a terminal parent boundary->dehydrates descendant assets past a terminal parent boundary@tanstack/router-coresuite: 108 files, 1615 tests passed, 0 failed, no type errors.20px 20px 15px->0pxand removes the stylesheet link on navigation; patched build keeps both.Summary by CodeRabbit