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
- Replace hydrate_body() with hydrate_lazy() in the client entry when any route is lazy.
- Remove lazy() wrappers from route components so all routes are statically available, keeping hydrate_body.
- 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
- Pick the hydration API based on route style: lazy -> hydrate_lazy, static -> hydrate_body.
- Keep entry-point templates in sync with route definitions when adding lazy().
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
- <FlatRoutes> should not be used with nested routes.
- failed to read hash file
- could not read manifest file
- there to be a <html> element
- missing <head> element
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/8e2530bb4317058d.
Report an issue: GitHub.