Skip to content

Fog of war loading state on initial renderΒ #14556

@Nirva-Software

Description

@Nirva-Software

Firstly, thank you very much for your amazing work on the project.
I have been using react-router for multiple major versions now, and each upgrade went smoothly and improved code simplicity, so thank you!

Reproduction

Go to https://stackblitz.com/edit/vitejs-react-router-rj9zjrdj?file=src%2Frouter.tsx, edit the url of the preview to add '/fow/home' and run the preview.

Edit: After digging a little more, I modified a test to reproduce my issue

diff --git a/packages/react-router/__tests__/router/lazy-discovery-test.ts b/packages/react-router/__tests__/router/lazy-discovery-test.ts
index 93b73e719..6d5577bee 100644
--- a/packages/react-router/__tests__/router/lazy-discovery-test.ts
+++ b/packages/react-router/__tests__/router/lazy-discovery-test.ts
@@ -999,9 +999,18 @@ describe("Lazy Route Discovery (Fog of War)", () => {
     expect(router.state.initialized).toBe(false);
     expect(router.state.matches.map((m) => m.route.id)).toEqual(["parent"]);
 
+    expect(router.state.navigation).toMatchObject({
+      state: "loading",
+      location: { pathname: "/parent/child" },
+    });
+
     loaderDfd.resolve("PARENT");
     expect(router.state.initialized).toBe(false);
     expect(router.state.matches.map((m) => m.route.id)).toEqual(["parent"]);
+    expect(router.state.navigation).toMatchObject({
+      state: "loading",
+      location: { pathname: "/parent/child" },
+    });
 
     childrenDfd.resolve([
       {
@@ -1012,8 +1021,17 @@ describe("Lazy Route Discovery (Fog of War)", () => {
     ]);
     expect(router.state.initialized).toBe(false);
     expect(router.state.matches.map((m) => m.route.id)).toEqual(["parent"]);
+    expect(router.state.navigation).toMatchObject({
+      state: "loading",
+      location: { pathname: "/parent/child" },
+    });
 
     childLoaderDfd.resolve("CHILD");
+
+    expect(router.state.navigation).toMatchObject({
+      state: "loading",
+      location: { pathname: "/parent/child" },
+    });
     await tick();
     expect(router.state.initialized).toBe(true);
     expect(router.state.location.pathname).toBe("/parent/child");
@@ -1025,6 +1043,7 @@ describe("Lazy Route Discovery (Fog of War)", () => {
       "parent",
       "child",
     ]);
+    expect(router.state.navigation).toMatchObject(IDLE_NAVIGATION);
   });
 
   it("discovers routes during initial SPA renders when a splat route matches", async () => {

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 20.19.1 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.8.2 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    react-router: ^7.9.6 => 7.9.6 
    vite: ^7.2.2 => 7.2.2

Used Package Manager

npm

Expected Behavior

Expected behavior is to have the 'Navigation state' set to 'loading' and the content displaying 'Loading...' during the first few seconds when the route is loaded.

Actual Behavior

The 'Navigation state' stays at 'idle' and the content displays 'Not found'. After a few seconds, the content changes to the actual content of the page.

Additional information

I used the patch below to fix the tests, and the other tests seem to run fine too, but I did not run the integration tests.

diff --git a/packages/react-router/lib/router/router.ts b/packages/react-router/lib/router/router.ts
index 23155b758..949a2e7c2 100644
--- a/packages/react-router/lib/router/router.ts
+++ b/packages/react-router/lib/router/router.ts
@@ -2044,6 +2044,8 @@ export function createRouter(init: RouterInit): Router {
             flushSync,
           },
         );
+      // } else if (initialMatchesIsFOW) {
+      //   updateState({ navigation: loadingNavigation }, { flushSync });
       }
 
       let discoverResult = await discoverRoutes(

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions