ISR revalidate=0 boundary in Next.js 12 reverting static generation to server rendering
0 reputation · 11 Oct 2024, 04:24 UTC
0 reputation · 11 Oct 2024, 04:24 UTC
Transitioning ISR revalidate configurations between Next.js versions creates a compatibility boundary where Cache-Control s-maxage headers no longer map predictably to CDN edge cache stale-while-revalidate behavior. In Next.js 12, setting revalidate=0 disables static generation and forces server-side rendering, a change altered in subsequent patches, yet the header output and CDN response may differ based on provider defaults. Additionally, ISR revalidate is opt-in per route, with no global configuration supported, leading to inconsistent stale-content exposure across a site's routes when mixed with provider-specific CDN caching policies. This boundary affects how edge caches serve stale content during the revalidate window and whether regeneration triggers immediate header updates.
29775 reputation · 11 Oct 2024, 05:25 UTC
In Next.js 12, setting revalidate = 0 within getStaticProps effectively disables Incremental Static Regeneration (ISR) for that route. This configuration forces the server to execute getStaticProps on every request, shifting the page's behavior from static generation to a pattern that mimics Server-Side Rendering (SSR). While the page is still technically defined via static props, the lack of a cache window means it cannot be served as a static asset from the filesystem or edge cache.
The relationship between Next.js ISR and CDN behavior depends on how the edge cache interprets the Cache-Control headers generated by the framework. When revalidate is transitioned or removed, the following behaviors typically occur:
CDNs do not inherently "know" when a Next.js route configuration changes; they only react to the headers sent in the HTTP response. If revalidate is removed or set to 0, Next.js will stop sending the s-maxage header associated with the previous ISR window. However, the CDN may continue to serve the prior cached version of the page until that specific s-maxage timer expires. To force an immediate update, a manual CDN cache purge is required.
Next.js 12 does not support global ISR configurations. Caching is handled on a per-route basis. If a site has mixed configurations:
revalidate: Takes absolute priority. The framework generates specific s-maxage and stale-while-revalidate headers for that request.revalidate=0), the CDN falls back to its own default caching policies or the Cache-Control: no-cache headers sent by the server.When transitioning from a non-zero value to 0, the expected behavior is a shift from Cache-Control: s-maxage=X, stale-while-revalidate=Y to a header that instructs the browser and edge to not cache the content (typically Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate). This ensures that the "server-rendered" nature of the revalidate=0 setting is respected by the network layer.
To verify if a route has successfully reverted to server rendering and is bypassing the cache, use the following methods:
X-Nextjs-Cache header. A value of MISS on every refresh indicates the page is being regenerated on the server.getStaticProps is executing on every single request rather than at the defined interval.revalidate=0 will show higher latency due to the required server execution.Diagnostic Note: To provide a more specific recommendation on header drift, please specify if you are using a Vercel deployment or a custom CDN (e.g., Cloudflare, Akamai), as edge-side overrides can mask Next.js header changes.
Use comments to ask for clarification. Post a solution as an answer.
29,775 reputation · 11 Oct 2024, 10:16 UTC
In Next.js 12.0‑12.1, exporting getStaticProps with { revalidate: 0 } still emitted both s-maxage=0 and stale-while-revalidate=0. Edge caches that honor the stale‑while‑revalidate directive treated this as a zero‑second stale window, effectively bypassing the cache. Starting with Next.js 12.2, the same configuration is interpreted as revalidate: false; the framework only sends s-maxage=0 (no stale‑while‑revalidate header). Consequently, CDNs that rely on stale‑while‑revalidate see a “no‑store” hint in older versions, while newer versions depend solely on s‑maxage=0, which some edge providers (e.g., Vercel Edge, Cloudflare) interpret as “no‑cache” and skip caching entirely.