diff --git a/src/core/session.js b/src/core/session.js index 1e9f1c7bd..78610dfbd 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -217,11 +217,21 @@ export class Session { } historyPoppedWithEmptyState(location) { + // Don't inject Turbo state on pages with data-turbo="false" — it would cause + // restore visits on subsequent back/forward, replacing the DOM despite Turbo being disabled + if (this.pageHasTurboDisabled()) return + this.history.replace(location) this.view.lastRenderedLocation = location this.view.cacheSnapshot() } + pageHasTurboDisabled() { + const body = document.body?.getAttribute("data-turbo") + const html = document.documentElement?.getAttribute("data-turbo") + return body === "false" || html === "false" + } + // Scroll observer delegate scrollPositionChanged(position) { diff --git a/src/tests/fixtures/data_turbo_false_hash_routing.html b/src/tests/fixtures/data_turbo_false_hash_routing.html new file mode 100644 index 000000000..5d3708384 --- /dev/null +++ b/src/tests/fixtures/data_turbo_false_hash_routing.html @@ -0,0 +1,27 @@ + + +
+ +Current hash:
+ + + + + diff --git a/src/tests/functional/navigation_tests.js b/src/tests/functional/navigation_tests.js index 25d11b887..cf6830abb 100644 --- a/src/tests/functional/navigation_tests.js +++ b/src/tests/functional/navigation_tests.js @@ -425,6 +425,25 @@ test("same-page anchor visits do not trigger visit events", async ({ page }) => } }) +test("history.back on data-turbo=false page with hash routing does not trigger restore visit", async ({ page }) => { + await page.goto("/src/tests/fixtures/data_turbo_false_hash_routing.html") + await readEventLogs(page) + + await page.click("#link-step1") + await page.click("#link-step2") + await page.click("#link-step3") + + await page.goBack() + await expect(page).toHaveURL(withPathname("/src/tests/fixtures/data_turbo_false_hash_routing.html")) + await expect(page).toHaveURL(withHash("#step2")) + expect(await noNextEventNamed(page, "turbo:visit")).toEqual(true) + + await page.goBack() + await expect(page).toHaveURL(withPathname("/src/tests/fixtures/data_turbo_false_hash_routing.html")) + await expect(page).toHaveURL(withHash("#step1")) + expect(await noNextEventNamed(page, "turbo:visit")).toEqual(true) +}) + test("correct referrer header", async ({ page }) => { page.click("#headers-link") await nextEventNamed(page, "turbo:load")