Skip to content

Commit ff041d1

Browse files
authored
Fix initial matching in fog of war when a splat route matches (#11759)
1 parent eb30a88 commit ff041d1

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

.changeset/rich-bees-invent.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 initial matching in fog of war when a splat route matches

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
},
106106
"filesize": {
107107
"packages/router/dist/router.umd.min.js": {
108-
"none": "56.3 kB"
108+
"none": "56.4 kB"
109109
},
110110
"packages/react-router/dist/react-router.production.min.js": {
111111
"none": "14.9 kB"

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

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,34 @@ describe("Lazy Route Discovery (Fog of War)", () => {
541541
expect(router.state.matches.map((m) => m.route.id)).toEqual(["a", "b"]);
542542
});
543543

544+
it("de-prioritizes splat routes in favor of looking for better async matches (splat/*)", async () => {
545+
router = createRouter({
546+
history: createMemoryHistory(),
547+
routes: [
548+
{
549+
path: "/",
550+
},
551+
{
552+
id: "splat",
553+
path: "/splat/*",
554+
},
555+
],
556+
async unstable_patchRoutesOnMiss({ matches, patch }) {
557+
await tick();
558+
patch(null, [
559+
{
560+
id: "static",
561+
path: "/splat/static",
562+
},
563+
]);
564+
},
565+
});
566+
567+
await router.navigate("/splat/static");
568+
expect(router.state.location.pathname).toBe("/splat/static");
569+
expect(router.state.matches.map((m) => m.route.id)).toEqual(["static"]);
570+
});
571+
544572
it("matches splats when other paths don't pan out", async () => {
545573
router = createRouter({
546574
history: createMemoryHistory(),
@@ -628,6 +656,39 @@ describe("Lazy Route Discovery (Fog of War)", () => {
628656
]);
629657
});
630658

659+
it("discovers routes during initial hydration when a splat route matches", async () => {
660+
let childrenDfd = createDeferred<AgnosticDataRouteObject[]>();
661+
662+
router = createRouter({
663+
history: createMemoryHistory({ initialEntries: ["/test"] }),
664+
routes: [
665+
{
666+
path: "/",
667+
},
668+
{
669+
path: "*",
670+
},
671+
],
672+
async unstable_patchRoutesOnMiss({ path, patch, matches }) {
673+
let children = await childrenDfd.promise;
674+
patch(null, children);
675+
},
676+
});
677+
router.initialize();
678+
expect(router.state.initialized).toBe(false);
679+
680+
childrenDfd.resolve([
681+
{
682+
id: "test",
683+
path: "/test",
684+
},
685+
]);
686+
await tick();
687+
expect(router.state.initialized).toBe(true);
688+
expect(router.state.location.pathname).toBe("/test");
689+
expect(router.state.matches.map((m) => m.route.id)).toEqual(["test"]);
690+
});
691+
631692
it("discovers new root routes", async () => {
632693
let childrenDfd = createDeferred<AgnosticDataRouteObject[]>();
633694
let childLoaderDfd = createDeferred();
@@ -737,7 +798,7 @@ describe("Lazy Route Discovery (Fog of War)", () => {
737798
let childLoaderDfd = createDeferred();
738799

739800
router = createRouter({
740-
history: createMemoryHistory(),
801+
history: createMemoryHistory({ initialEntries: ["/other"] }),
741802
routes: [
742803
{
743804
id: "other",

packages/router/router.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,20 @@ 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) {
848+
let fogOfWar = checkFogOfWar(
849+
initialMatches,
850+
dataRoutes,
851+
init.history.location.pathname
852+
);
853+
if (fogOfWar.active) {
854+
initialMatches = null;
855+
}
856+
}
857+
844858
let initialized: boolean;
845859
if (!initialMatches) {
846860
// We need to run patchRoutesOnMiss in initialize()
@@ -3162,7 +3176,10 @@ export function createRouter(init: RouterInit): Router {
31623176
return { active: true, matches: fogMatches || [] };
31633177
} else {
31643178
let leafRoute = matches[matches.length - 1].route;
3165-
if (leafRoute.path === "*") {
3179+
if (
3180+
leafRoute.path &&
3181+
(leafRoute.path === "*" || leafRoute.path.endsWith("/*"))
3182+
) {
31663183
// If we matched a splat, it might only be because we haven't yet fetched
31673184
// the children that would match with a higher score, so let's fetch
31683185
// around and find out

0 commit comments

Comments
 (0)