{"record":{"id":"8f495545b085f504","repo":"DioxusLabs/dioxus","slug":"a-router-must-be-present-to-use-navigator","errorCode":null,"errorMessage":"A router must be present to use navigator","messagePattern":"A router must be present to use navigator","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/router/src/contexts/navigator.rs","lineNumber":13,"sourceCode":"use crate::{ExternalNavigationFailure, NavigationTarget, RouterContext};\n\n/// Acquire the navigator without subscribing to updates.\n///\n/// Can be called anywhere in the application provided a Router has been initialized.\n///\n/// ## Panics\n///\n/// Panics if there is no router present.\npub fn navigator() -> Navigator {\n    Navigator(\n        dioxus_core::try_consume_context::<RouterContext>()\n            .expect(\"A router must be present to use navigator\"),\n    )\n}\n\n/// A view into the navigation state of a router.\n#[derive(Clone, Copy)]\npub struct Navigator(pub(crate) RouterContext);\n\nimpl Navigator {\n    /// Check whether there is a previous page to navigate back to.\n    #[must_use]\n    pub fn can_go_back(&self) -> bool {\n        self.0.can_go_back()\n    }\n\n    /// Check whether there is a future page to navigate forward to.\n    #[must_use]\n    pub fn can_go_forward(&self) -> bool {\n        self.0.can_go_forward()","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/router/src/contexts/navigator.rs#L1-L31","documentation":"navigator() acquires the RouterContext that a Router component provides to its subtree. Without a Router ancestor the context doesn't exist, try_consume_context returns None, and the expect panics. Unlike a hook, navigator() may be called from anywhere inside RSX or event handlers, but still only under a mounted Router.","triggerScenarios":"Calling navigator() in a tree that never mounts a Router (plain dioxus::launch(Component) app, LaunchBuilder without a Routable root), or invoking it in a context outside the component tree (background tasks, server code).","commonSituations":"Adding navigator().push(...) navigation to a small demo or test app that has no router set up; refactoring a component out of a routed app into a library; calling navigator in code paths that also run on the server.","solutions":["Wrap your app in a Router: define #[derive(Routable)] enum Route and launch the router (Router::<Route> {})","If a component must work with or without a router, gate the call: check try_consume_context::<RouterContext>() first","For optional navigation, fall back to staying on the current view when the context is absent"],"exampleFix":"// before\nrsx! { button { onclick: move |_| navigator().push(\"/settings\"), \"Go\" } } // no Router mounted\n// after\n#[derive(Clone, Routable)]\nenum Route { #[route(\"/settings\")] Settings {}, #[route(\"/\")] Home {} }\n// root component:\nrsx! { Router::<Route> {} }","handlingStrategy":"type-guard","validationCode":"if dioxus::prelude::try_consume_context::<dioxus::router::RouterContext>().is_some() {\n    let nav = dioxus::router::navigator();\n    nav.push(\"/settings\");\n} else {\n    // no router mounted: fall back (inert link, no-op, or render Router first)\n}","typeGuard":"fn router_present() -> bool {\n    dioxus::prelude::try_consume_context::<dioxus::router::RouterContext>().is_some()\n}","tryCatchPattern":null,"preventionTips":["Mount Router::<Route> {} once at the app root before using any navigation API","In shared/library components, check for the RouterContext before calling navigator()","Keep navigation calls inside the RSX tree of a routed app"],"tags":["router","navigator","context","routing","panic"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}