DEV Community

Understanding Next.js Page Caching (with a real example)

How Next.js caching works

Next.js (App Router) handles HTML caching at the edge in production. For statically prerendered pages, it sets Cache-Control: s-maxage=31536000, which is one year. This header tells CDNs and edge caches that they can serve the page without re-fetching for a long time. Browser cache headers such as no-cache do not override this because s-maxage takes priority for shared caches.

This explains why the listing page showed stale content while individual article pages, which are either dynamic or use revalidation, updated immediately.

How to control caching

Next.js provides a clean way to manage page freshness. First, set revalidation for a page. In the page file, for example app/writing/page.tsx, add:

export const revalidate = 60; // seconds

The page is served from cache for 60 seconds. After 60 seconds, the next visitor triggers background regeneration. Visitors continue to get a fast response while the page updates.

For instant updates after saving content, use on-demand revalidation:

import { revalidatePath } from 'next/cache';
revalidatePath('/writing');

Call this in your article save logic, whether that is a CMS, API route, or webhook, to invalidate the cached page immediately.

Key lessons from my experience

  • Edge caching is powerful, but it can make pages seem stale if revalidation is not configured.
  • Browser cache clearing or changing Nginx headers does not affect HTML caching for statically prerendered pages.
  • The correct place to control page freshness is in the Next.js route itself, not the server or CDN alone.
  • By adding a single line of code to the route, I now get the perfect balance: fast cached pages that still update reliably when I add or edit content.

References

  • Next.js ISR and Self-hosting
  • Next.js Caching and Revalidation
  • Next.js Config and Headers

Comments

No comments yet. Start the discussion.