fix(app-router): restore shallow pathname on history traversal - #2829
fix(app-router): restore shallow pathname on history traversal#2829GtechGovind wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee5604e238
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 126007f9e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e4bdabd84
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f54ae1f078
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (isSameAppRoutePopstateTarget(href)) { | ||
| notifyAppRouterTransitionStart(href, "traverse"); | ||
| historyController.commitTraversalIndexFromHistoryState(event.state); | ||
| commitClientNavigationState(); |
There was a problem hiding this comment.
Restore snapshots before taking the same-route shortcut
When traversal skips intermediate entries, the target URL can match the currently rendered route while its saved tree differs. For example, create a shallow /page entry, navigate through /other to a newly rendered /page, then call history.go(-2): this branch only synchronizes URL hooks and leaves the newer /page tree mounted instead of restoring the shallow entry's snapshot. Check for a restorable shallow snapshot before taking this pathname/search shortcut.
Useful? React with 👍 / 👎.
|
|
||
| remember(options: { bfcacheVersion: number; historyIndex: number | null; state: TState }): void { | ||
| pruneAfter(historyIndex: number | null): void { | ||
| if (historyIndex === null) return; |
There was a problem hiding this comment.
Prune forward snapshots when the current index is unknown
Fresh evidence beyond the earlier retention fix: traversing to a metadata-less entry sets the current traversal index to null, so a subsequent shallow push calls this method with null and returns without pruning even though the browser has discarded the entire forward branch. Repeating Back to that metadata-less entry followed by pushState() leaves another unreachable durable React tree in memory each time, and general cache invalidation does not clear durable snapshots. Prune using explicit branch ownership even when the previous index is unknown.
AGENTS.md reference: AGENTS.md:L483-L483
Useful? React with 👍 / 👎.
Summary
history.pushStateandhistory.replaceStateentriesusePathnameanduseSearchParamswhen popstate takes the same-route fast pathRoot cause
External History API calls updated Vinext's navigation-hook URL cache, but the App Router popstate fast path only restored history metadata and scroll position. It did not resynchronize the hooks when traversing back to the rendered route. The pushed entry also lacked a marker that would let forward traversal reuse the current tree instead of attempting an RSC navigation.
The new internal shallow URL metadata identifies those entries, allowing popstate to synchronize the URL-backed hooks while preserving the current App Router tree.
Fixes #1541.
Validation
./node_modules/.bin/vp check./node_modules/.bin/vp test run tests/shims.test.ts -t 'preserves App Router history metadata when external history calls provide caller state'PLAYWRIGHT_PROJECT=app-router ./node_modules/.bin/playwright test tests/e2e/app-router/advanced.spec.ts -g 'Shallow Routing'(4 passed, 1 existing fixme skipped)