From 4cd09653652892c8d4193464ba28eeb5d31f4470 Mon Sep 17 00:00:00 2001 From: Tom Heaton Date: Mon, 28 Sep 2026 11:25:11 +0100 Subject: [PATCH] fix: don't throw when history.state is null after replaceState --- .changeset/null-history-state-depth.md | 5 +++++ src/routers/history.ts | 2 +- test/browser-history.spec.ts | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changeset/null-history-state-depth.md create mode 100644 test/browser-history.spec.ts diff --git a/.changeset/null-history-state-depth.md b/.changeset/null-history-state-depth.md new file mode 100644 index 00000000..2570b354 --- /dev/null +++ b/.changeset/null-history-state-depth.md @@ -0,0 +1,5 @@ +--- +"@solidjs/router": patch +--- + +`browserHistory()` no longer throws when `history.state` is still null after `replaceState` (seen in iOS WKWebView embeds) diff --git a/src/routers/history.ts b/src/routers/history.ts index 5a3bde4f..205448b8 100644 --- a/src/routers/history.ts +++ b/src/routers/history.ts @@ -16,7 +16,7 @@ export function saveCurrentDepth() { if (!window.history.state || window.history.state._depth == null) { window.history.replaceState({ ...window.history.state, _depth: window.history.length - 1 }, ""); } - depth = window.history.state._depth; + depth = window.history.state?._depth ?? window.history.length - 1; } function keepDepth(state: any) { diff --git a/test/browser-history.spec.ts b/test/browser-history.spec.ts new file mode 100644 index 00000000..c49e7987 --- /dev/null +++ b/test/browser-history.spec.ts @@ -0,0 +1,13 @@ +import { afterEach, describe, expect, test, vi } from "vitest"; +import { browserHistory } from "../src/index.js"; + +describe("browserHistory", () => { + afterEach(() => vi.restoreAllMocks()); + + test("does not throw when replaceState leaves history.state null", () => { + vi.spyOn(window.history, "state", "get").mockReturnValue(null); + vi.spyOn(window.history, "replaceState").mockImplementation(() => {}); + + expect(() => browserHistory()).not.toThrow(); + }); +});