Skip to content

Commit

Permalink
Set Next-Router-Stale-Time header from collected stale times
Browse files Browse the repository at this point in the history
This is only done during prerender which is typically the only things we
prefetch (other than loading.tsx).
  • Loading branch information
sebmarkbage committed Oct 14, 2024
1 parent f847dae commit 6c52126
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/next/src/client/components/app-router-headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const NEXT_ROUTER_PREFETCH_HEADER = 'Next-Router-Prefetch' as const
// be merged into a single enum.
export const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER =
'Next-Router-Segment-Prefetch' as const
export const NEXT_ROUTER_STALE_TIME_HEADER = 'Next-Router-Stale-Time' as const
export const NEXT_HMR_REFRESH_HEADER = 'Next-HMR-Refresh' as const
export const NEXT_URL = 'Next-Url' as const
export const RSC_CONTENT_TYPE_HEADER = 'text/x-component' as const
Expand Down
7 changes: 7 additions & 0 deletions packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
NEXT_HMR_REFRESH_HEADER,
NEXT_ROUTER_PREFETCH_HEADER,
NEXT_ROUTER_STATE_TREE_HEADER,
NEXT_ROUTER_STALE_TIME_HEADER,
NEXT_URL,
RSC_HEADER,
} from '../../client/components/app-router-headers'
Expand Down Expand Up @@ -1114,6 +1115,12 @@ async function renderToHTMLOrFlightImpl(
metadata.fetchTags = response.collectedTags.join(',')
}

// Let the client router know how long to keep the cached entry around.
const staleHeader = String(response.collectedStale)
res.setHeader(NEXT_ROUTER_STALE_TIME_HEADER, staleHeader)
metadata.headers ??= {}
metadata.headers[NEXT_ROUTER_STALE_TIME_HEADER] = staleHeader

// If force static is specifically set to false, we should not revalidate
// the page.
if (workStore.forceStatic === false || response.collectedRevalidate === 0) {
Expand Down
7 changes: 7 additions & 0 deletions packages/next/src/server/use-cache/use-cache-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ function generateCacheEntryWithCacheContext(
'A default cacheLife profile must always be provided. This is a bug in Next.js.'
)
}

// Initialize the Store for this Cache entry.
const cacheStore: UseCacheStore = {
type: 'cache',
Expand Down Expand Up @@ -239,9 +240,15 @@ function propagateCacheLifeAndTags(
outerTags.push(tag)
}
}
if (workUnitStore.stale > entry.stale) {
workUnitStore.stale = entry.stale
}
if (workUnitStore.revalidate > entry.revalidate) {
workUnitStore.revalidate = entry.revalidate
}
if (workUnitStore.expire > entry.expire) {
workUnitStore.expire = entry.expire
}
}
}

Expand Down
1 change: 1 addition & 0 deletions test/e2e/app-dir/use-cache/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const nextConfig = {
dynamicIO: true,
cacheLife: {
frequent: {
stale: 19,
revalidate: 100,
},
},
Expand Down
10 changes: 10 additions & 0 deletions test/e2e/app-dir/use-cache/use-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ describe('use-cache', () => {
}
)

itSkipTurbopack(
'should match the expected stale config in the page header',
async () => {
const meta = JSON.parse(
await next.readFile('.next/server/app/cache-tag.meta')
)
expect(meta.headers['Next-Router-Stale-Time']).toBe('19')
}
)

itSkipTurbopack(
'should propagate unstable_cache tags correctly',
async () => {
Expand Down

0 comments on commit 6c52126

Please sign in to comment.