Skip to content

[Bug?]: when using FileRoutes initial navigation happens after delay & Suspense doesn't do anything #1969

Closed

Description

@illiaChaban

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

When using FileRoutes with Suspense like in the official example, Suspense doesn't do anything and fallback isn't being displayed.

    <Router root={(props) => <Suspense fallback={<div>loading...</div>}>{props.children}</Suspense>}>
      <FileRoutes />
    </Router>

The current behavior on the initial page navigation (page A > page B) is this:

  1. user clicks link ( element or button with manual "useNavigate" handling)
  2. "navigate" is called
  3. next page's assets load
  4. url is updated
  5. new page is displayed

Notice, that fallback page is never displayed and url is only updated after next page assets fully load

Expected behavior 🤔

  1. user clicks link
  2. "navigate" is called
  3. url is updated (without delay) & Suspence fallback page is shown
  4. next page's assets load
  5. new page is displayed

Steps to reproduce 🕹

Stackblitz example

Steps:

  1. create 2 linked pages (either use component or button with manual "useNavigate") with FileRoutes
  2. add "fallback" parameter to top level Suspence
  3. add a long running resource on page B so it's easier to spot what's going on (createResource(() => wait(5000)))
  4. compile, navigate from page A to page B
  5. observe: link clicked > nothing happens (assets load) > url & page updated

Context 🔦

I believe this is unexpected behavior and it doesn't work well with "view transition api"

Your environment 🌎

npmPackages:
    "@solidjs/router": "^0.15.3",
    "@solidjs/start": "^1.1.7",
    "solid-js": "^1.9.9",
    "vinxi": "^0.5.8"

Activity

  1. illiaChaban commented on Sep 8, 2025

    @illiaChaban
    Author

    actually, this seems to have the same behavior for manual routes:

    
    const Landing = lazy(() => import('./routes/index'));
    const About = lazy(() => import('./routes/about'));
    
    export default function App() {
      return (
        <Router
          root={(props) => (
            <>
              <Nav />
              <Suspense fallback={<div>loading...</div>}>{props.children}</Suspense>
            </>
          )}
        >
          <Route path="" component={Landing} />
          <Route path="/about" component={About} />
        </Router>
      );
    }
    

    Maybe this is a bug with Router / root prop itself ?

  2. zhangxichang commented on Dec 21, 2025

    @zhangxichang

    me too

  3. birkskyum commented on Jul 25, 2026

    @birkskyum
    Member

    Duplicate of

    If you want the URL to update immediately and the fallback to show, re-mount the boundary per navigation:

    root={props => {
      const location = useLocation();
      return (
        <>
          <Nav />
          <Show keyed when={location.pathname}>
            <Suspense fallback={<div>loading...</div>}>{props.children}</Suspense>
          </Show>
        </>
      );
    }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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