I recently ran into an interesting issue while working on the /writing page of my site. Whenever I added or updated articles, the changes did not show immediately. Oddly enough, the individual article pages updated as expected, but the listing page stayed stale.
After some digging, I realized this was not a bug. It was Next.js doing exactly what it is supposed to.
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.