From 996d57eba64f5568d7984a4f8609d98bca5cbbba Mon Sep 17 00:00:00 2001 From: Andres Date: Wed, 1 Jul 2026 12:59:03 -0700 Subject: [PATCH] fix: stop 404s/redirects from being publicly CDN-cached The catch-all getServerSideProps set 'public, max-age=3600' plus Surrogate-Control and the instance Surrogate-Key at the top of the function, before knowing the outcome. Non-200 exits (notFound, redirects) inherited those headers, so a transient 404 on a valid route (e.g. /instances/ during a deploy window) could be pinned at the Fastly edge and served to everyone -- including logged-in users -- until a manual instance purge. Default every response to 'private, no-store' and apply the cacheable headers only on the confirmed 200 page render. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/pages/[[...zesty]].js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/pages/[[...zesty]].js b/src/pages/[[...zesty]].js index d46f18740..4e35587b1 100644 --- a/src/pages/[[...zesty]].js +++ b/src/pages/[[...zesty]].js @@ -75,17 +75,11 @@ export async function getServerSideProps({ req, res, resolvedUrl }) { // does not display with npm run dev res.setHeader('set-cookie', `PRODUCTION=${process.env.PRODUCTION}`); - isProd && - res.setHeader( - 'Cache-Control', - 'public, max-age=3600, stale-while-revalidate=7200 ', - ); - isProd && res.setHeader('Surrogate-Control', 'max-age=3600'); - res.setHeader( - 'Surrogate-Key', - `${process.env.zesty.instance_zuid}, zesty.io`, - ); + // Default to non-cacheable; cache headers are set only on the 200 path below + // so 404s/redirects can't be pinned at the CDN edge and served to everyone. + res.setHeader('Cache-Control', 'private, no-store'); + // Fetch the page data using the cache function let data = await fetchPage(resolvedUrl); // attempt to get page data relative to zesty @@ -160,6 +154,19 @@ export async function getServerSideProps({ req, res, resolvedUrl }) { }; } + // Real 200 page: safe to cache and tag with the instance Surrogate-Key. + if (isProd) { + res.setHeader( + 'Cache-Control', + 'public, max-age=3600, stale-while-revalidate=7200', + ); + res.setHeader('Surrogate-Control', 'max-age=3600'); + res.setHeader( + 'Surrogate-Key', + `${process.env.zesty.instance_zuid}, zesty.io`, + ); + } + // Pass data to the page via props return { props: { ...data } }; }