leptos-rs/leptos · error

lazy routes should not be used with hydrate_body(); use hydr

Error message

lazy routes should not be used with hydrate_body(); use hydrate_lazy() instead

What it means

When hydrating with hydrate_body(), the flat router requires all routes to already be loaded; if the matched route is lazy (code-split via LazyRoute/lazy()), it panics because lazy route components must be fetched before body hydration. The dedicated hydrate_lazy() API first loads the lazy route, then hydrates.

Source

Thrown at router/src/flat_router.rs:732

                    ScopedFuture::new(async move {
                        OwnedView::new(view.choose().await)
                    })
                }));

                match view.as_mut().now_or_never() {
                    Some(view) => Rc::new(RefCell::new(FlatRoutesViewState {
                        view: view
                            .into_any()
                            .hydrate::<FROM_SERVER>(cursor, position),
                        id,
                        owner,
                        params,
                        path,
                        url,
                        matched,
                    })),
                    None => {
                        panic!(
                            "lazy routes should not be used with \
                             hydrate_body(); use hydrate_lazy() instead"
                        );
                    }
                }
            }
        }
    }

    async fn hydrate_async(
        self,
        cursor: &Cursor,
        position: &PositionState,
    ) -> Self::State {
        let FlatRoutesView {
            current_url,
            routes,
            fallback,

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Replace hydrate_body() with hydrate_lazy() in the client entry when any route is lazy.
  2. Remove lazy() wrappers from route components so all routes are statically available, keeping hydrate_body.
  3. Check the entry point matches the route style: static routes -> hydrate_body, lazy routes -> hydrate_lazy.

Example fix

// before
leptos::mount::hydrate_body(App); // panics if a matched route is lazy()

// after
leptos::mount::hydrate_lazy(App); // loads lazy route chunks before hydrating
Defensive patterns

Strategy: validation

Validate before calling

// before calling hydrate_body, ensure no matched route is lazy
if route_tree.has_lazy_routes() { leptos::mount::hydrate_lazy(App); } else { leptos::mount::hydrate_body(App); }

Prevention

When it happens

Trigger: Using FlatRoutes::hydrate_body (or hydrate_body at the app root) while the matched route is defined with lazy() / Lazy::new or LazyRoute — i.e. the resolved match is a lazy (None variant) route.

Common situations: Code-splitting route components for smaller bundles while still calling hydrate_body in the client entry; older templates using hydrate_body updated to include lazy routes; mixing hydrate_body and lazy route definitions after a refactor.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/8e2530bb4317058d. Report an issue: GitHub.