{"record":{"id":"51d3b320885f3eee","repo":"DioxusLabs/dioxus","slug":"access-to-window","errorCode":null,"errorMessage":"access to `window`","messagePattern":"access to `window`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/web/src/history.rs","lineNumber":48,"sourceCode":"    /// Create a new [`WebHistory`].\n    ///\n    /// If `do_scroll_restoration` is [`true`], [`WebHistory`] will take control of the history\n    /// state. It'll also set the browsers scroll restoration to `manual`.\n    pub fn new(prefix: Option<String>, do_scroll_restoration: bool) -> Self {\n        let myself = Self::new_inner(prefix, do_scroll_restoration);\n\n        let current_route = dioxus_history::History::current_route(&myself);\n        let current_route_str = current_route.to_string();\n        let prefix_str = myself.prefix.as_deref().unwrap_or(\"\");\n        let current_url = format!(\"{prefix_str}{current_route_str}\");\n        let state = myself.create_state();\n        let _ = replace_state_with_url(&myself.history, &state, Some(&current_url));\n\n        myself\n    }\n\n    fn new_inner(prefix: Option<String>, do_scroll_restoration: bool) -> Self {\n        let window = window().expect(\"access to `window`\");\n        let history = window.history().expect(\"`window` has access to `history`\");\n\n        if do_scroll_restoration {\n            history\n                .set_scroll_restoration(ScrollRestoration::Manual)\n                .expect(\"`history` can set scroll restoration\");\n        }\n\n        let prefix = prefix\n            // If there isn't a base path, try to grab one from the CLI\n            .or_else(dioxus_cli_config::web_base_path)\n            // Normalize the prefix to start and end with no slashes\n            .as_ref()\n            .map(|prefix| prefix.trim_matches('/'))\n            // If the prefix is empty, don't add it\n            .filter(|prefix| !prefix.is_empty())\n            // Otherwise, start with a slash\n            .map(|prefix| format!(\"/{prefix}\"));","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/web/src/history.rs#L30-L66","documentation":"`WebHistory::new(prefix, do_scroll_restoration)` - the browser History implementation behind the Dioxus router - immediately runs `window().expect(\"access to `window`\")` in `new_inner`. Without a Window global (web worker, server/SSR process, headless test runtime), construction panics before routing ever starts.","triggerScenarios":"Constructing WebHistory outside the browser main thread; a fullstack server build that instantiates web history because the router integration was not cfg-gated; wasm-bindgen-test creating a router outside a page.","commonSituations":"Shared routing setup code compiled into both server and client targets; running the app inside a worker; integration tests exercising navigation logic headlessly.","solutions":["Construct WebHistory only in browser builds (`#[cfg(target_arch = \"wasm32\")]`)","On the server or in tests, provide a MemoryHistory (`Rc<dyn History>`) instead - this is what dioxus fullstack/desktop renderers do","Check `web_sys::window().is_some()` before choosing the history implementation"],"exampleFix":"// before: constructed unconditionally, panics on server/worker\nlet history = Rc::new(WebHistory::new(None, true)) as Rc<dyn History>;\n// after: pick per environment\nlet history = if web_sys::window().is_some() {\n    Rc::new(WebHistory::new(None, true)) as Rc<dyn History>\n} else {\n    Rc::new(MemoryHistory::default()) as Rc<dyn History>\n};","handlingStrategy":"type-guard","validationCode":"// choose the history implementation before constructing\nif web_sys::window().is_none() {\n    // not a browser main thread: do not construct WebHistory here\n    let history: Rc<dyn History> = Rc::new(MemoryHistory::default());\n    // ... provide it to the router and return\n}","typeGuard":"fn can_use_web_history() -> bool {\n    web_sys::window().is_some()\n}","tryCatchPattern":null,"preventionTips":["Construct WebHistory only inside #[cfg(target_arch = \"wasm32\")] browser builds","Provide MemoryHistory for SSR/tests - the same pattern dioxus fullstack and desktop renderers use","Check web_sys::window().is_some() before selecting a history implementation in shared code"],"tags":["dioxus-web","router","history","window","wasm","panic"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}