DioxusLabs/dioxus · error

`history` can set scroll restoration

Error message

`history` can set scroll restoration

What it means

When scroll restoration is enabled, the WebHistory constructor calls `history.set_scroll_restoration(ScrollRestoration::Manual).expect("`history` can set scroll restoration")`. In browsers whose History API lacks `scrollRestoration`, the web-sys call throws and the expect panics during router startup - so the app dies at history construction, before any routing happens.

Source

Thrown at packages/web/src/history.rs:54

        let current_route = dioxus_history::History::current_route(&myself);
        let current_route_str = current_route.to_string();
        let prefix_str = myself.prefix.as_deref().unwrap_or("");
        let current_url = format!("{prefix_str}{current_route_str}");
        let state = myself.create_state();
        let _ = replace_state_with_url(&myself.history, &state, Some(&current_url));

        myself
    }

    fn new_inner(prefix: Option<String>, do_scroll_restoration: bool) -> Self {
        let window = window().expect("access to `window`");
        let history = window.history().expect("`window` has access to `history`");

        if do_scroll_restoration {
            history
                .set_scroll_restoration(ScrollRestoration::Manual)
                .expect("`history` can set scroll restoration");
        }

        let prefix = prefix
            // If there isn't a base path, try to grab one from the CLI
            .or_else(dioxus_cli_config::web_base_path)
            // Normalize the prefix to start and end with no slashes
            .as_ref()
            .map(|prefix| prefix.trim_matches('/'))
            // If the prefix is empty, don't add it
            .filter(|prefix| !prefix.is_empty())
            // Otherwise, start with a slash
            .map(|prefix| format!("/{prefix}"));

        Self {
            do_scroll_restoration,
            history,
            prefix,
            window,

View on GitHub (pinned to 393d190a80)

Solutions

  1. Construct with scroll restoration disabled: `WebHistory::new(prefix, false)`
  2. Upgrade the target browser/webview - every modern engine supports History.scrollRestoration
  3. Feature-detect `scrollRestoration` before constructing and only pass true when it exists (and report upstream so the constructor degrades gracefully instead of panicking)

Example fix

// before: panics on browsers without History.scrollRestoration
let history = WebHistory::new(None, true);
// after: enable scroll restoration only when the API exists
let supported = web_sys::window()
    .and_then(|w| w.history().ok())
    .map(|h| js_sys::Reflect::get(h.as_ref(), &JsValue::from_str("scrollRestoration")).is_ok())
    .unwrap_or(false);
let history = WebHistory::new(None, supported);
Defensive patterns

Strategy: validation

Validate before calling

fn supports_scroll_restoration() -> bool {
    web_sys::window()
        .and_then(|w| w.history().ok())
        .map(|h| js_sys::Reflect::get(h.as_ref(), &wasm_bindgen::JsValue::from_str("scrollRestoration")).is_ok())
        .unwrap_or(false)
}
// pass supports_scroll_restoration() as do_scroll_restoration

Prevention

When it happens

Trigger: Constructing WebHistory with do_scroll_restoration=true in a browser without History.scrollRestoration support: IE11, old Safari, legacy Android WebView / embedded engines, minimal headless engines with a partial History API.

Common situations: Corporate environments pinned to legacy browsers; kiosk or embedded devices shipping old webviews; CI headless engines missing parts of the History API.

Related errors


AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16). Data as JSON: /api/errors/df143fc71cc0373b. Report an issue: GitHub.