Skip to content

Commit 4b13939

Browse files
fix: scroll restoration upon browser forward navigation
1 parent 0e0a281 commit 4b13939

3 files changed

Lines changed: 36 additions & 18 deletions

File tree

.changeset/fifty-eagles-breathe.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/router-core': patch
3+
---
4+
5+
Fix a regression where browser back/forward navigation could fail to restore the previous scroll position for an existing history entry.

e2e/react-router/scroll-restoration-sandbox-vite/tests/app.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,37 @@ test('Smoke - Renders home', async ({ page }) => {
99
).toBeVisible()
1010
})
1111

12+
test('restores the prior scroll position after browser back then forward', async ({
13+
page,
14+
}) => {
15+
await page.goto(toRuntimePath('/'))
16+
await page.getByRole('link', { name: 'Head-/normal-page' }).click()
17+
await page.waitForURL('**/normal-page')
18+
await expect(page.getByTestId('at-the-top')).toBeInViewport()
19+
20+
const scrollY = await page.evaluate(async () => {
21+
window.scrollTo(0, document.documentElement.scrollHeight)
22+
await new Promise((resolve) => requestAnimationFrame(() => resolve(null)))
23+
return window.scrollY
24+
})
25+
26+
expect(scrollY).toBeGreaterThan(0)
27+
await expect(page.getByTestId('at-the-bottom')).toBeInViewport()
28+
29+
await page.goBack()
30+
await expect(
31+
page.getByRole('heading', { name: 'Welcome Home!' }),
32+
).toBeVisible()
33+
34+
await page.goForward()
35+
await page.waitForURL('**/normal-page')
36+
await page.waitForFunction(
37+
(expectedScrollY) => Math.abs(window.scrollY - expectedScrollY) <= 2,
38+
scrollY,
39+
)
40+
await expect(page.getByTestId('at-the-bottom')).toBeInViewport()
41+
})
42+
1243
const pages = [
1344
linkOptions({ to: '/normal-page' }),
1445
linkOptions({ to: '/lazy-page' }),

packages/router-core/src/scroll-restoration.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -258,24 +258,6 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
258258
return
259259
}
260260

261-
const fromIndex = event.fromLocation?.state.__TSR_index
262-
const toIndex = event.toLocation.state.__TSR_index
263-
// Clear on forward navigations, and on same-entry replace navigations where
264-
// the href changed. Preserve back/restore entries so they can be restored.
265-
const shouldClearCache =
266-
typeof fromIndex === 'number' && typeof toIndex === 'number'
267-
? toIndex > fromIndex ||
268-
(toIndex === fromIndex &&
269-
event.fromLocation?.href !== event.toLocation.href)
270-
: true
271-
272-
if (shouldClearCache) {
273-
cache.set((state) => {
274-
delete state[cacheKey]
275-
return state
276-
})
277-
}
278-
279261
ignoreScroll = true
280262

281263
try {

0 commit comments

Comments
 (0)