From f01a098dc954ab529973603bb55ac54e3ab99190 Mon Sep 17 00:00:00 2001 From: Jackie Li Date: Fri, 12 Jun 2026 20:39:14 +0100 Subject: [PATCH] fix hx-browser-indicator history back() #3838 --- src/ext/hx-browser-indicator.js | 2 + test/test.html | 1 + test/tests/ext/hx-browser-indicator.js | 53 ++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 test/tests/ext/hx-browser-indicator.js diff --git a/src/ext/hx-browser-indicator.js b/src/ext/hx-browser-indicator.js index 5fc8f6c34..1f7451ace 100644 --- a/src/ext/hx-browser-indicator.js +++ b/src/ext/hx-browser-indicator.js @@ -44,7 +44,9 @@ function startIndicator() { listenForNavigate(); + const historyState = history.state; navigation.navigate(location.href, { history: 'replace' }); + history.replaceState(historyState, ''); } function stopIndicator() { diff --git a/test/test.html b/test/test.html index fa5d0a9d1..f31698c93 100644 --- a/test/test.html +++ b/test/test.html @@ -156,6 +156,7 @@ + diff --git a/test/tests/ext/hx-browser-indicator.js b/test/tests/ext/hx-browser-indicator.js new file mode 100644 index 000000000..326f96bb0 --- /dev/null +++ b/test/tests/ext/hx-browser-indicator.js @@ -0,0 +1,53 @@ +describe("hx-browser-indicator extension", function () { + let extBackup; + + before(async () => { + extBackup = backupExtensions(); + clearExtensions(); + htmx.config.extensions = "browser-indicator"; + htmx.__approvedExt = "browser-indicator"; + + let script = document.createElement("script"); + script.src = "../src/ext/hx-browser-indicator.js"; + await new Promise((resolve) => { + script.onload = resolve; + document.head.appendChild(script); + }); + }); + + after(() => { + restoreExtensions(extBackup); + }); + + beforeEach(() => { + setupTest(this.currentTest); + }); + + afterEach(() => { + htmx.config.boostBrowserIndicator = false; + cleanupTest(); + }); + + it("preserves the current entry history state across the indicator (per-element)", async function () { + history.replaceState({ htmx: true, sentinel: 42 }, ""); + mockResponse("GET", "/page2", "loaded"); + let btn = createProcessedHTML( + '', + ); + btn.click(); + await forRequest(); + assert.deepEqual(history.state, { htmx: true, sentinel: 42 }); + }); + + it("preserves the current entry history state across the indicator (boosted)", async function () { + htmx.config.boostBrowserIndicator = true; + history.replaceState({ htmx: true, sentinel: 7 }, ""); + mockResponse("GET", "/page2", "loaded"); + createProcessedHTML( + '
go
', + ); + find("#a1").click(); + await forRequest(); + assert.deepEqual(history.state, { htmx: true, sentinel: 7 }); + }); +});