offline navigations: bootstrap fallback from router records (8/10)#93644
Conversation
Failing test suitesCommit: 9b75037 | About building and testing Next.js
Expand output● offlineNavigations deploy-safe runtime behavior › registers the service worker and serves current-build assets from Cache Storage ● offlineNavigations deploy-safe runtime behavior › recovers a viewport-prefetched route while offline
Expand output● offlineNavigations deploy-safe runtime behavior › registers the service worker and serves current-build assets from Cache Storage ● offlineNavigations deploy-safe runtime behavior › recovers a viewport-prefetched route while offline
Expand output● app dir - prefetching › should immediately render the loading state for a dynamic segment when fetched from higher up in the tree |
e09c281 to
4c6ecad
Compare
b18a178 to
6caa377
Compare
4c6ecad to
e3deb55
Compare
6caa377 to
221b216
Compare
e3deb55 to
01a7f84
Compare
221b216 to
f670ded
Compare
Stats from current PR🔴 2 regressions
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (9 files)Files with changes:
View diffsapp-page-exp..ntime.dev.jsfailed to diffapp-page-exp..time.prod.jsfailed to diffapp-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsfailed to diffapp-page-tur..ntime.dev.jsfailed to diffapp-page-tur..time.prod.jsfailed to diffapp-page.runtime.dev.jsfailed to diffapp-page.runtime.prod.jsfailed to diffserver.runtime.prod.jsDiff too large to display 📎 Tarball URLCommit: 51b4120 |
f670ded to
3507830
Compare
6c811a7 to
d3fabe5
Compare
fafaefd to
729b785
Compare
c020b0a to
284bcf2
Compare
003cef8 to
5bdc788
Compare
284bcf2 to
4f0c762
Compare
5bdc788 to
5d7a3d7
Compare
4f0c762 to
895dca0
Compare
5d7a3d7 to
3912e67
Compare
3912e67 to
0ac0ca3
Compare
2b33f40 to
a05b5dc
Compare
ab7f2f7 to
a9a70a6
Compare
6b46e75 to
bb45b28
Compare
a9a70a6 to
bfb04d5
Compare
bb45b28 to
f214891
Compare
bfb04d5 to
a8eb471
Compare
f214891 to
6c47dfd
Compare
a8eb471 to
ea85d06
Compare
6c47dfd to
6a7cdd4
Compare
ea85d06 to
51b4120
Compare
6a7cdd4 to
f71c4f2
Compare
51b4120 to
00b5b5b
Compare
f71c4f2 to
3b4189c
Compare
00b5b5b to
9b75037
Compare
Stack Position
This is PR 8 of 10. It is the first PR where a prefetched route can survive an offline hard reload.
Review guide:
https://gist.github.com/feedthejim/a10f757cf07c5550f731adf2fcf1077b
Full Stack
offline navigations: add gated build primitives (1/10)offline navigations: generate fallback document artifacts (2/10)offline navigations: register pass-through worker (3/10)offline navigations: cache fallback and current-build assets (4/10)offline navigations: serve fallback document offline (5/10)offline navigations: add router-cache persistence primitives (6/10)offline navigations: persist cached router records (7/10)offline navigations: bootstrap fallback from router records (8/10)offline navigations: support dynamic route patterns (9/10)offline navigations: add docs and examples (10/10)What This Changes
This connects the fallback document to the persisted router cache. On an offline hard reload:
This PR also folds the replay coverage from the now-closed #93650 into the core bootstrap slice.
What Works After This PR
A visible Link that was viewport-prefetched through the normal router can be hard-loaded while offline and recover from persisted router records. Missing head or segment data misses visibly.
router.refresh()and mutation/server-action invalidation clear the persisted offline copy through the same invalidation path as the regular router cache.What Does Not Work Yet
Dynamic route pattern replay is still deferred to PR 9. The local deploy-mode harness timed out before deploying, so true deployed proof remains pending CI or a custom deploy run.
Reviewer Focus
Please focus on bootstrap/routing architecture. The service worker should only deliver the fallback document; the existing client router should own replay eligibility, record reads, misses, and invalidation.
Proof in This PR
Core replay, missing-record misses, request-sensitive misses, URL-shape misses, and invalidation are covered by:
pnpm jest --runTestsByPath packages/next/src/client/components/router-reducer/offline-navigation-cache.test.ts --runInBandHEADLESS=true pnpm test-start-turbo test/e2e/app-dir/offline-navigations-deploy/offline-navigations-deploy.test.tsHEADLESS=true pnpm test-start-turbo test/production/app-dir/offline-navigations/offline-navigations.test.tsHEADLESS=true pnpm test-start-webpack test/production/app-dir/offline-navigations/offline-navigations.test.tsDeferred Coverage
PR 9 widens replay to learned dynamic route patterns. Broader storage pressure, custom miss UI, dev simulation, and output export integration remain follow-up work, not part of this first usable stack.
Docs Status
The user-facing guide and config reference land in PR 10.