leptos-rs/leptos · error
You cannot call `use_navigate` outside a <Router>.
Error message
You cannot call `use_navigate` outside a <Router>.
What it means
use_navigate requires routing context that only exists inside a <Router> component. Calling it outside — e.g. in a top-level module, plain function, or component rendered above the Router — panics because the navigation handle cannot be found in context.
Source
Thrown at router/src/hooks.rs:277
}
})
}
/// Returns a function that can be used to navigate to a new route.
///
/// This should only be called on the client; it does nothing during
/// server rendering.
///
/// ```rust
/// # if false { // can't actually navigate, no <Router/>
/// let navigate = leptos_router::hooks::use_navigate();
/// navigate("/", Default::default());
/// # }
/// ```
#[track_caller]
pub fn use_navigate() -> impl Fn(&str, NavigateOptions) + Clone {
let cx = use_context::<RouterContext>()
.expect("You cannot call `use_navigate` outside a <Router>.");
move |path: &str, options: NavigateOptions| cx.navigate(path, options)
}
/// Returns a reactive string that contains the route that was matched for
/// this [`Route`](crate::components::Route).
#[track_caller]
pub fn use_matched() -> Memo<String> {
use_context::<Matched>()
.expect("use_matched called outside a matched Route")
.0
.into()
}
View on GitHub (pinned to 32d20f6c9d)
Solutions
- Move the component or function that calls `use_navigate()` inside the `<Router>` tree.
- For programmatic navigation outside components, restructure to trigger navigation from within the router tree (e.g. a signal consumed by an in-router component), or use the `redirect` mechanism available in that context.
- In tests, wrap with a MemoryRouter-based `<Router>`.
Example fix
// before
fn logout() {
let navigate = use_navigate(); // panics: called in a module fn outside tree
navigate("/login", Default::default());
}
// after
#[component]
fn LogoutButton() -> impl IntoView {
let navigate = use_navigate();
view! { <button on:click=move |_| navigate("/login", Default::default())>Logout</button> }
} Defensive patterns
Strategy: fallback
Validate before calling
// Inside a component, verify context before navigating: let navigate_fn = use_context::<RouterContext>().map(|cx| move |p: &str| cx.navigate(p, Default::default()));
Type guard
fn can_navigate() -> bool { use_context::<RouterContext>().is_some() } Prevention
- Trigger programmatic navigation only from components inside <Router>.
- Don't stash navigate functions in globals or call them from outside the tree.
- For auth redirects, place a redirecting component inside the router.
When it happens
Trigger: Calling `use_navigate()` in a component outside the `<Router>` tree (e.g. a login page or toast rendered above the router), in event handlers set up before the router mounts, or in tests without a router wrapper.
Common situations: Redirect-on-auth logic placed outside the router; navigation helpers called from global event listeners; storybook/test setups rendering components standalone.
Related errors
- Tried to access Location outside a <Router>.
- called use_resolved_path outside a <Router>
- use_matched called outside a matched Route
- tried to use <A/> outside a <Router/>.
- <Outlet/> used without RouteContext being provided.
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/641815b96bf207fc.
Report an issue: GitHub.