diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 1e50f2754a776..d16122ff2ce41 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -3292,7 +3292,10 @@ export default abstract class Server< // If cache control is already set on the response we don't // override it to allow users to customize it via next.config - if (cacheEntry.revalidate && !res.getHeader('Cache-Control')) { + if ( + typeof cacheEntry.revalidate !== 'undefined' && + !res.getHeader('Cache-Control') + ) { res.setHeader( 'Cache-Control', formatRevalidate({ @@ -3315,7 +3318,10 @@ export default abstract class Server< } else if (cachedData.kind === CachedRouteKind.REDIRECT) { // If cache control is already set on the response we don't // override it to allow users to customize it via next.config - if (cacheEntry.revalidate && !res.getHeader('Cache-Control')) { + if ( + typeof cacheEntry.revalidate !== 'undefined' && + !res.getHeader('Cache-Control') + ) { res.setHeader( 'Cache-Control', formatRevalidate({ @@ -3339,17 +3345,33 @@ export default abstract class Server< return null } } else if (cachedData.kind === CachedRouteKind.APP_ROUTE) { - const headers = { ...cachedData.headers } + const headers = fromNodeOutgoingHttpHeaders(cachedData.headers) if (!(this.minimalMode && isSSG)) { - delete headers[NEXT_CACHE_TAGS_HEADER] + headers.delete(NEXT_CACHE_TAGS_HEADER) + } + + // If cache control is already set on the response we don't + // override it to allow users to customize it via next.config + if ( + typeof cacheEntry.revalidate !== 'undefined' && + !res.getHeader('Cache-Control') && + !headers.get('Cache-Control') + ) { + headers.set( + 'Cache-Control', + formatRevalidate({ + revalidate: cacheEntry.revalidate, + expireTime: this.nextConfig.expireTime, + }) + ) } await sendResponse( req, res, new Response(cachedData.body, { - headers: fromNodeOutgoingHttpHeaders(headers), + headers, status: cachedData.status || 200, }) ) diff --git a/test/production/standalone-mode/required-server-files/app/api/test/[slug]/route.js b/test/production/standalone-mode/required-server-files/app/api/test/[slug]/route.js new file mode 100644 index 0000000000000..b0a419c985786 --- /dev/null +++ b/test/production/standalone-mode/required-server-files/app/api/test/[slug]/route.js @@ -0,0 +1,7 @@ +export const dynamic = 'force-static' + +export async function GET(request, context) { + const { params } = context + const { slug } = params + return Response.json({ message: `Hello, ${slug}!` }) +} diff --git a/test/production/standalone-mode/required-server-files/app/test/[slug]/page.jsx b/test/production/standalone-mode/required-server-files/app/test/[slug]/page.jsx new file mode 100644 index 0000000000000..7cd62bbcf0db6 --- /dev/null +++ b/test/production/standalone-mode/required-server-files/app/test/[slug]/page.jsx @@ -0,0 +1,9 @@ +export const revalidate = 3600 + +export default function Page() { + return