Skip to content

fix(history): stamp history depth from the current entry, not history.length (1.x) - #708

Open
sarankumar1325 wants to merge 1 commit into
solidjs:mainfrom
sarankumar1325:fix/history-depth-capped-length-1x
Open

sarankumar1325 wants to merge 1 commit into
solidjs:mainfrom
sarankumar1325:fix/history-depth-capped-length-1x

Conversation

@sarankumar1325

Copy link
Copy Markdown

Fixes #694 (1.x side)

This is the main (1.x) counterpart of #695 and #707, which fixed the same bug on next.

Problem

saveCurrentDepth() in src/lifecycle.ts stamps an unstamped entry with _depth: history.length - 1, and set() in Router / HashRouter pushed the caller's state without a depth, so every router push got stamped that way. Browsers cap session history (50 entries in Chromium and Firefox). Once the cap is reached, pushState drops the oldest entry and history.length stays the same, so each new entry got the same _depth as the one below it. Back then computed delta = 0, which skipped useBeforeLeave, and scroll restoration put consecutive entries in the same slot.

Change

  • src/lifecycle.ts:
  • src/routers/Router.ts and src/routers/HashRouter.ts: push with nextDepth(state). Replace still uses keepDepth, and user state is kept.
  • test/history-depth.spec.tsx: four tests.
    • Router and HashRouter, with history.length mocked at the 50-entry cap: push three times, then replace once. They expect depths [49, 50, 51, 51]. Without the change they get [49, 49, 49, 49].
    • User state is kept next to the stamp.
    • An entry pushed outside the router is stamped one above the last depth.
  • A patch changeset.

All four tests fail without the src change.

Testing

  • pnpm test (vitest + test:types): 17 files, 263 tests passed
  • pnpm build

AI disclosure: I used an AI assistant to help write this change and its tests. I reviewed the diff and ran the checks above.

….length

Browsers cap session history (50 entries in Chromium and Firefox). Once
the cap is reached, pushState drops the oldest entry and history.length
stays the same, so `history.length - 1` gave every new entry the depth
of the one below it. Back then computed a zero delta (useBeforeLeave was
skipped) and scroll restoration shared one slot between entries.

Router and HashRouter now stamp a pushed entry with the current depth
+ 1, and saveCurrentDepth() stamps an entry the router didn't push
(e.g. a #anchor jump) one above the last known depth, falling back to
history.length only when no depth is known. Replace keeps the current
depth as before.

This is the 1.x counterpart of solidjs#695 and solidjs#707 on `next`.

Fixes solidjs#694
@changeset-bot

changeset-bot Bot commented Oct 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bf196cd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@solidjs/router Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useBeforeLeave and scroll restoration break on Back after 50 history entries (_depth taken from the capped history.length)

1 participant