fix(app-router): cache static navigation shells#1916
Draft
NathanDrake2406 wants to merge 2 commits into
Draft
Conversation
Cached navigations only reused full visited Flight responses, so static segment data from the initial HTML or a prior navigation was not staged separately. That diverged from Next.js Segment Cache behavior and broke cached-navigation freshness, especially when a data-cache hit dropped cacheLife stale metadata. Add a static-navigation-shell render mode that suspends request-bound APIs at their Suspense boundaries, seed and consume client shell entries, and preserve stale cacheLife metadata across data-cache hits so shell freshness follows the cached content contract.
commit: |
Contributor
Author
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Member
|
/bigbonk review for issues |
Contributor
|
@james-elicx Bonk workflow was cancelled. View workflow run · To retry, trigger Bonk again. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
unstable_instant = { prefetch: "runtime" }allows runtime request APIs exceptconnection().packages/vinext/src/server/app-page-dispatch.ts,packages/vinext/src/server/app-page-render.ts,packages/vinext/src/server/app-browser-entry.ts,packages/vinext/src/shims/cache-runtime.tsWhy
Cached navigation correctness depends on keeping static, runtime-prefetchable, and dynamic request-bound work in separate stages. Next.js Segment Cache can reuse the static stage while dynamic boundaries are still waiting on a fresh navigation request; vinext previously only reused full visited Flight responses, and data-cache hits also dropped
cacheLife().stale, so initial-HTML fully static shells stayed fresh for the wrong duration.static-navigation-shellRSC mode and shell-scoped suspension forconnection,headers,cookies, and pagesearchParams.cacheLife({ stale })controls shell reuse after data-cache hits too.staleinCacheControlMetadataso shell TTL survives"use cache"HITs.What changed
connection()for cached navigation.unstable_instant.prefetch = "runtime"includes runtime request API output while still deferringconnection().Maintainer review path
tests/e2e/app-router-bfcache/cached-navigations.spec.tsandtests/fixtures/app-bfcache/app/nextjs-compat/cached-navigations/for the upstream behavior port.packages/vinext/src/server/app-static-navigation-shell.ts,packages/vinext/src/shims/headers.ts,packages/vinext/src/shims/server.ts, andpackages/vinext/src/server/app-page-search-params-observation.tsfor request API suspension.packages/vinext/src/server/app-page-dispatch.tsandpackages/vinext/src/server/app-page-render.tsfor shell lifecycle and response headers.packages/vinext/src/server/app-browser-entry.tsfor client shell seeding, replay, partial commit behavior, and stale TTL.packages/vinext/src/shims/cache.tsandpackages/vinext/src/shims/cache-runtime.tsfor stale metadata preservation across data-cache hits.Validation
vp checkvp test run tests/app-page-element-builder.test.tsvp test run tests/shims.test.ts -t '"use cache" runtime'vp test run tests/ppr-fallback-shell.test.tsvp test run tests/thenable-params.test.tsvp test run tests/next-config.test.ts -t "cachedNavigations|appShells|detectNextIntlConfig"CI=1 PLAYWRIGHT_PROJECT=app-router-bfcache pnpm run test:e2e -- cached-navigations.spec.ts --retries=0vp env exec --node 24 ./scripts/run-nextjs-deploy-suite.sh /Users/nathan/Projects/vinext/.refs/nextjs-v16.2.6 --retries 0 -c 1 --debug test/e2e/app-dir/segment-cache/cached-navigations/cached-navigations.test.tsThe exact upstream deploy-suite file passes 9/9.
Risk / compatibility
experimental.cachedNavigationsis now read intoResolvedNextConfigand only enabled when paired withcacheComponents.stale; existingrevalidateandexpirebehavior is unchanged.Non-goals
unstable_postpone; vinext uses a shell render compatibility path instead.References
stalefield that controls client cache reuse.