Skip to content

Commit 9e1da44

Browse files
authored
Fix fog of war hydration in SSR apps that matched a splat route on the server (#11790)
1 parent da65120 commit 9e1da44

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

.changeset/wicked-ducks-heal.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@remix-run/router": patch
3+
---
4+
5+
Fix fog of war hydration in SSR apps that matched a splat route on the server

packages/router/__tests__/lazy-discovery-test.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ describe("Lazy Route Discovery (Fog of War)", () => {
656656
]);
657657
});
658658

659-
it("discovers routes during initial hydration when a splat route matches", async () => {
659+
it("discovers routes during initial SPA renders when a splat route matches", async () => {
660660
let childrenDfd = createDeferred<AgnosticDataRouteObject[]>();
661661

662662
router = createRouter({
@@ -669,7 +669,7 @@ describe("Lazy Route Discovery (Fog of War)", () => {
669669
path: "*",
670670
},
671671
],
672-
async unstable_patchRoutesOnMiss({ path, patch, matches }) {
672+
async unstable_patchRoutesOnMiss({ patch }) {
673673
let children = await childrenDfd.promise;
674674
patch(null, children);
675675
},
@@ -689,6 +689,37 @@ describe("Lazy Route Discovery (Fog of War)", () => {
689689
expect(router.state.matches.map((m) => m.route.id)).toEqual(["test"]);
690690
});
691691

692+
it("does not discover routes during initial SSR hydration when a splat route matches", async () => {
693+
router = createRouter({
694+
history: createMemoryHistory({ initialEntries: ["/test"] }),
695+
routes: [
696+
{
697+
path: "/",
698+
},
699+
{
700+
id: "splat",
701+
loader: () => "SPLAT 2",
702+
path: "*",
703+
},
704+
],
705+
hydrationData: {
706+
loaderData: {
707+
splat: "SPLAT 1",
708+
},
709+
},
710+
async unstable_patchRoutesOnMiss() {
711+
throw new Error("Should not be called");
712+
},
713+
});
714+
router.initialize();
715+
716+
await tick();
717+
expect(router.state.initialized).toBe(true);
718+
expect(router.state.location.pathname).toBe("/test");
719+
expect(router.state.loaderData.splat).toBe("SPLAT 1");
720+
expect(router.state.matches.map((m) => m.route.id)).toEqual(["splat"]);
721+
});
722+
692723
it("discovers new root routes", async () => {
693724
let childrenDfd = createDeferred<AgnosticDataRouteObject[]>();
694725
let childLoaderDfd = createDeferred();

packages/router/router.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -841,10 +841,13 @@ export function createRouter(init: RouterInit): Router {
841841
initialErrors = { [route.id]: error };
842842
}
843843

844-
// If the user provided a patchRoutesOnMiss implementation and our initial
845-
// match is a splat route, clear them out so we run through lazy discovery
846-
// on hydration in case there's a more accurate lazy route match
847-
if (initialMatches && patchRoutesOnMissImpl) {
844+
// In SPA apps, if the user provided a patchRoutesOnMiss implementation and
845+
// our initial match is a splat route, clear them out so we run through lazy
846+
// discovery on hydration in case there's a more accurate lazy route match.
847+
// In SSR apps (with `hydrationData`), we expect that the server will send
848+
// up the proper matched routes so we don't want to run lazy discovery on
849+
// initial hydration and want to hydrate into the splat route.
850+
if (initialMatches && patchRoutesOnMissImpl && !init.hydrationData) {
848851
let fogOfWar = checkFogOfWar(
849852
initialMatches,
850853
dataRoutes,

0 commit comments

Comments
 (0)