Skip to content

Commit 829741f

Browse files
committed
fix: don't permamently cache fallback html
1 parent d0fda7e commit 829741f

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

src/run/handlers/request-context.cts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export type RequestContext = {
1111
responseCacheGetLastModified?: number
1212
responseCacheKey?: string
1313
responseCacheTags?: string[]
14-
usedFsRead?: boolean
14+
usedFsReadForNonFallback?: boolean
1515
didPagesRouterOnDemandRevalidate?: boolean
1616
serverTiming?: string
1717
routeHandlerRevalidate?: NetlifyCachedRouteValue['revalidate']

src/run/headers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export const setCacheControlHeaders = (
263263
cacheControl === null &&
264264
!headers.has('cdn-cache-control') &&
265265
!headers.has('netlify-cdn-cache-control') &&
266-
requestContext.usedFsRead
266+
requestContext.usedFsReadForNonFallback
267267
) {
268268
// handle CDN Cache Control on static files
269269
headers.set('cache-control', 'public, max-age=0, must-revalidate')

src/run/next.cts

+31-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import fs from 'fs/promises'
1+
import fs, { readFile } from 'fs/promises'
22
import { relative, resolve } from 'path'
33

44
// @ts-expect-error no types installed
55
import { patchFs } from 'fs-monkey'
6+
import { type PrerenderManifest } from 'next/dist/build/index.js'
67

78
import { getRequestContext } from './handlers/request-context.cjs'
89
import { getTracer } from './handlers/tracer.cjs'
@@ -80,6 +81,30 @@ console.timeEnd('import next server')
8081

8182
type FS = typeof import('fs')
8283

84+
function normalizeStaticAssetPath(path: string) {
85+
// just skip leading / for now
86+
return path.replace(/^\/+/g, '')
87+
}
88+
89+
let fallbacks: Array<string> | undefined
90+
async function isFallbackHTML(relPath: string) {
91+
if (!fallbacks) {
92+
fallbacks = []
93+
94+
try {
95+
const prerenderManifest = JSON.parse(
96+
await readFile(resolve('.next/prerender-manifest.json'), 'utf-8'),
97+
) as PrerenderManifest
98+
fallbacks = Object.values(prerenderManifest.dynamicRoutes)
99+
.map((route) => route.fallback)
100+
.filter((fallback) => typeof fallback === 'string')
101+
.map(normalizeStaticAssetPath)
102+
} catch {}
103+
}
104+
105+
return fallbacks.includes(normalizeStaticAssetPath(relPath))
106+
}
107+
83108
export async function getMockedRequestHandlers(...args: Parameters<typeof getRequestHandlers>) {
84109
const tracer = getTracer()
85110
return tracer.withActiveSpan('mocked request handler', async () => {
@@ -100,9 +125,11 @@ export async function getMockedRequestHandlers(...args: Parameters<typeof getReq
100125
const relPath = relative(resolve('.next/server/pages'), path)
101126
const file = await store.get(await encodeBlobKey(relPath))
102127
if (file !== null) {
103-
const requestContext = getRequestContext()
104-
if (requestContext) {
105-
requestContext.usedFsRead = true
128+
if (!(await isFallbackHTML(relPath))) {
129+
const requestContext = getRequestContext()
130+
if (requestContext) {
131+
requestContext.usedFsReadForNonFallback = true
132+
}
106133
}
107134

108135
return file

0 commit comments

Comments
 (0)