Skip to content

Commit ab7f2f7

Browse files
committed
offline navigations: bootstrap fallback from router records (8/10)
1 parent 0ac0ca3 commit ab7f2f7

12 files changed

Lines changed: 1683 additions & 63 deletions

File tree

packages/next/offline.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
export { useOffline } from './dist/client/components/use-offline'
1+
export {
2+
clearOfflineNavigationCache,
3+
useOffline,
4+
} from './dist/client/components/use-offline'

packages/next/src/build/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4112,6 +4112,7 @@ export default async function build(
41124112
buildId,
41134113
buildManifest,
41144114
crossOrigin: config.crossOrigin,
4115+
deploymentId: config.deploymentId,
41154116
})
41164117

41174118
if (fallbackDocument === null) {

packages/next/src/build/offline-navigation-fallback.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,21 @@ function getScriptAttributes(
3434
}
3535

3636
// Generate the build-scoped HTML entrypoint used by offline document fallback
37-
// handling. It intentionally contains only the app bootstrap, not route HTML,
38-
// so the artifact stays request-invariant.
37+
// handling. It intentionally contains only the app bootstrap, not route HTML;
38+
// route data is restored by the client from persisted router-cache records
39+
// after this document loads.
3940
export function createOfflineNavigationFallbackDocument({
4041
assetPrefix,
4142
buildId,
4243
buildManifest,
4344
crossOrigin,
45+
deploymentId,
4446
}: {
4547
assetPrefix: string
4648
buildId: string
4749
buildManifest: BuildManifest
4850
crossOrigin: '' | 'anonymous' | 'use-credentials' | undefined
51+
deploymentId: string | undefined
4952
}): string | null {
5053
const rootMainFiles = buildManifest.rootMainFiles.filter((file) =>
5154
file.endsWith('.js')
@@ -77,11 +80,15 @@ export function createOfflineNavigationFallbackDocument({
7780
source: 'offline-navigation-fallback',
7881
}
7982

83+
const deploymentIdAttribute = deploymentId
84+
? ` data-dpl-id="${htmlEscapeAttributeString(deploymentId)}"`
85+
: ''
86+
8087
return `<!DOCTYPE html><html data-next-offline-navigation-fallback="" data-build-id="${htmlEscapeAttributeString(
8188
buildId
82-
)}"><head><meta charSet="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="next-offline-navigation-fallback" content="1"><meta name="next-build-id" content="${htmlEscapeAttributeString(
89+
)}"${deploymentIdAttribute}><head><meta charSet="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="next-offline-navigation-fallback" content="1"><meta name="next-build-id" content="${htmlEscapeAttributeString(
8390
buildId
8491
)}"><script id="__NEXT_OFFLINE_NAVIGATION_FALLBACK" type="application/json">${htmlEscapeJsonString(
8592
JSON.stringify(metadata)
86-
)}</script></head><body><div id="__next"></div><script>self.__next_f=self.__next_f||[];self.__next_f.push([0])</script>${polyfillScripts}${bootstrapScripts}</body></html>`
93+
)}</script></head><body><div id="__next"></div><p id="__NEXT_OFFLINE_NAVIGATION_CACHE_MISS" hidden>This page is not available offline.</p><script>self.__next_f=self.__next_f||[];self.__next_f.push([0])</script>${polyfillScripts}${bootstrapScripts}</body></html>`
8794
}

packages/next/src/build/offline-navigation-service-worker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export function getOfflineNavigationServiceWorkerFilePath(): string {
1010

1111
// The first version of offline navigations uses a generated, app-local service
1212
// worker as a document fallback only. It is network-first for regular loads and
13-
// only serves the fallback document after the network request fails.
13+
// only serves the fallback document after the network request fails; route data
14+
// is restored later by the client from the durable router cache.
1415
export function createOfflineNavigationServiceWorker({
1516
buildId,
1617
cacheNamespace,

0 commit comments

Comments
 (0)