fix(link): avoid reusing dynamic app route prefetches#2450
Conversation
|
/bigbonk review for issues |
commit: |
|
There was a problem hiding this comment.
Review: fix(link): avoid reusing dynamic app route prefetches
Reviewed the shim change and its interaction with the navigation/prefetch reuse paths. No blocking issues found. The change is correct and internally consistent.
What the change does
resolveMatchedAutoAppRoutePrefetch now sets cacheForNavigation: !hasLoadingShell && !route.isDynamic (previously !hasLoadingShell). Dynamic routes without a loading shell now warm an optimistic shell (optimisticRouteShell: true) instead of caching a full payload keyed by concrete URL.
Correctness verification
- Navigation reuse is correctly gated.
navigation.ts:440andnavigation.ts:451skip entries wherecacheForNavigation === false, andnavigation.ts:871returnsnullfor them. So a dynamic auto-prefetch can no longer be reused as the authoritative nav payload — the click issues a fresh dynamic request, deriving params from the target tree. This matches the PR intent. - Shell entries are not wrongly promoted.
promotePrefetchEntriesForNavigation(link.tsx:672) skipsoptimisticRouteShell === trueentries, so the warmed dynamic shell won't be silently upgraded tocacheForNavigation: trueon click. unstable_dynamicOnHoverpath is unaffected. That test uses/blog/hellowherecanPrefetchLoadingShell: true, socacheForNavigationwas alreadyfalsebefore this change (!true==!true && !isDynamic). The test correctly required no update.- Test fixtures line up. The updated tests use
/clothing/1and/products/1(canPrefetchLoadingShell: false,isDynamic: true), which flip fromtrue->falseexactly as expected.
E2E test
The added lock-based test (parallel-route-navigations.spec.ts) is a faithful port. The page.route lock is installed before goto but lock is undefined until after the initial navigation settles, so the initial load passes through untouched. expect(hadLocked).toBe(1) under expectStable correctly asserts exactly one fresh request is issued on click (and stays 1 for the stable window), proving prefetch data isn't reused. Good coverage.
Checks run
vitest run tests/link.test.ts tests/link-navigation.test.ts— 175 passedvitest run tests/shims.test.ts— 1174 passedtsc --noEmit -p packages/vinext/tsconfig.json— clean
Minor observations (non-blocking)
canAutoPrefetchFullAppRouteis exported but only consumed by tests; the behavior change there is test-observable only. Fine as-is.- Parity: this is a client-side shim change, so the dev/prod server files (
prod-server.ts,worker-entry.ts) aren't affected — the reuse gating lives entirely in the sharednavigation.tsconsumption path, which all environments share.
LGTM.
|
Review posted to PR #2450. Summary of my findings: Review Result: No blocking issues — LGTMI reviewed the change ( Correctness confirmed:
E2E test: The lock-based test is a faithful port; the Verification I ran:
Only non-blocking notes: |
|
Deploy-suite run 28478866791 / job 84413308650 backlog check: this PR appears to cover the |
|
/bigbonk review for issues |
Review: fix(link): avoid reusing dynamic app route prefetchesI traced the core shim change and its interaction with the prefetch/navigation reuse paths, ran the unit tests, and audited the E2E wiring. The runtime logic is correct, but there is one CI-blocking test-configuration issue. Finding (blocking): new E2E spec runs against the dev server, where it will fail
"app-router": {
testDir: "./tests/e2e",
testMatch: ["**/app-router/**/*.spec.ts", "**/og-image.spec.ts"],
testIgnore: [appRouterBrowserSpecificTests, "**/app-router/nextjs-compat/client-cache.spec.ts"],
...
}The new spec lives at This is exactly why the sibling Suggested fix: add the new spec to the testIgnore: [
appRouterBrowserSpecificTests,
"**/app-router/nextjs-compat/client-cache.spec.ts",
"**/app-router/nextjs-compat/segment-cache-client-params.spec.ts",
],Correctness of the shim change (LGTM)
Minor (non-blocking)
Checks run
|
|
Review posted to PR #2450. SummaryI reviewed the PR (2 commits) which fixes reuse of dynamic App Router prefetches for parallel-route navigations. Blocking finding: new E2E spec will run against the dev server and likely fail in CI
Correctness (LGTM)
Minor (non-blocking, pre-existing)
Verification: |
|
/bigbonk review for issues |
Review: fix(link): avoid reusing dynamic app route prefetchesRe-reviewed after the two follow-up commits ( Prior blocking finding is fixedThe earlier review flagged that the new Correctness (verified)
Verification I ran
Non-blocking observations (not regressions from this PR)
|
|
Review posted to PR #2450. SummaryI re-reviewed the PR after the two follow-up commits and found no blocking issues — LGTM. Prior blocking finding resolved: The earlier review flagged that Correctness verified:
Verification I ran:
Non-blocking notes: |
|
Backlog recheck for deploy-suite run 28478866791 / job 84413308650: this PR already covers the remaining non-cacheComponents/use-cache functional failures in test/e2e/app-dir/segment-cache/encoded-slash-params/encoded-slash-params.test.ts when stacked with #2440. Skipping a duplicate implementation/worktree for this item. |
|
Backlog triage for deploy-suite run 28478866791 / job 84413308650: this PR already covers the non-cacheComponents/use-cache |
|
Backlog ownership note for deploy-suite run 28478866791 / job 84413308650:\n\n- Artifact row inspected: |
|
fatal: couldn't find remote ref codex/fix-parallel-route-navigation-params |
|
@james-elicx Bonk workflow failed. Check the logs for details. View workflow run · To retry, trigger Bonk again. |
Summary
Tests
vp test run tests/link.test.ts tests/link-navigation.test.tsPLAYWRIGHT_PROJECT=app-router pnpm run test:e2e -- tests/e2e/app-router/parallel-route-navigations.spec.tstest/e2e/app-dir/parallel-route-navigations/parallel-route-navigations.test.tsvp checkReview