Avoid build-time data staleness in SSG by using ISR for background updates, implementing on-demand revalidation via webhooks, leveraging client-side data fetching for dynamic content, and adopting hybrid rendering strategies
Build-time data staleness is an inherent challenge with Static Site Generation (SSG)—pages are generated at build time and remain fixed until the next build. As your content changes in your CMS, database, or API, users may see outdated information. Next.js provides several strategies to combat this staleness without sacrificing the performance benefits of static generation: Incremental Static Regeneration (ISR), on-demand revalidation, client-side data fetching for dynamic portions, and hybrid architectures that combine static shells with live data updates.
Incremental Static Regeneration (ISR): Set a revalidate time (e.g., 60 seconds) to automatically regenerate pages in the background when content becomes stale .
On-Demand Revalidation: Trigger immediate cache invalidation via revalidatePath or revalidateTag when content actually changes (e.g., via CMS webhooks) .
Client-side data fetching: Fetch real-time data in browser after the static page loads, keeping the static shell fast while ensuring fresh content .
Hybrid approach: Use SSG for stable content (product descriptions, blog posts) and client-side fetching for dynamic elements (inventory, comments, prices) .
Time-based rebuilds: For simple sites, schedule periodic rebuilds (e.g., every hour via cron jobs) to refresh content, though this is less efficient than ISR .
For highly dynamic data that changes frequently (like inventory levels, live comments, or user-specific content), the best approach is often to serve a static shell and fetch the dynamic data on the client. This gives you the performance benefits of SSG for the static content while ensuring users always see fresh data for the dynamic parts. The pattern is especially effective when combined with WebSockets or Server-Sent Events for real-time updates .
Critical vs. non-critical content: Use different revalidation strategies for different parts of your site. Product names and descriptions might use ISR with longer intervals (hours), while prices might use shorter intervals (minutes) or client-side fetching .
Segment-specific configuration: Next.js allows setting revalidate at the segment level via export const revalidate = value in layouts or pages, giving fine-grained control .
Combined approach: For maximum freshness, use on-demand ISR for core content changes (triggered by CMS webhooks) plus client-side polling for rapidly changing data like stock levels .
Static with fallback: Use fallback: 'blocking' (Pages Router) or dynamicParams: true (App Router) to generate rarely-accessed pages on-demand while keeping popular pages pre-rendered .
Next.js ISR implements the stale-while-revalidate caching pattern. When a page is requested after its revalidate time, Next.js serves the stale (cached) page immediately while triggering a background regeneration. This means users never wait for the page to generate—they see content instantly, and the next user gets the fresh version. This pattern is acceptable for most content types where slight staleness is preferable to slow page loads. The key is setting appropriate revalidate times based on how quickly content becomes outdated .
When to use: For sites where ISR isn't feasible (e.g., static export) or content changes predictably on a schedule .
Implementation: Set up cron jobs (GitHub Actions, Vercel Cron Jobs, AWS EventBridge) to trigger rebuilds at specific intervals .
Trade-offs: Simple to implement but rebuilds take time and may waste resources if content hasn't actually changed .
Example: A news site that publishes daily at 8 AM can schedule a rebuild for 8:05 AM each day, ensuring fresh morning content .
The best approach depends on your content characteristics: For content that changes predictably (blog posts, articles), ISR with time-based revalidation works well. For content that updates sporadically (product prices, inventory), on-demand revalidation triggered by your CMS or database is ideal. For highly dynamic content (live comments, stock ticks), client-side fetching after static shell is the right choice. Most production sites combine multiple strategies—using ISR for core content, on-demand for important updates, and client-side for real-time elements—to balance performance with freshness .