100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

Incremental Static Regeneration

Learn how Incremental Static Regeneration (ISR) lets Next.js update statically generated pages after deployment without a full rebuild.

Rendering ModelsIntermediate9 min readJul 10, 2026
Analogies

The Problem ISR Solves

Plain Static Site Generation freezes a page's HTML at build time; if underlying data changes, visitors keep seeing stale content until the site is rebuilt and redeployed. Incremental Static Regeneration (ISR) solves this by letting a statically generated page be regenerated in the background after a specified time window, without requiring a full site rebuild. In the App Router, this is enabled by passing a revalidate option to fetch, such as fetch(url, { next: { revalidate: 60 } }), which tells Next.js that cached data (and the page built from it) can be reused for up to 60 seconds before it's considered stale.

🏏

Cricket analogy: It's like a stadium's printed team-sheet board being reprinted fresh every hour during a long rain delay, rather than reprinting the whole match program from scratch or leaving yesterday's lineup posted all day.

Time-Based Revalidation

With time-based revalidation, the first request after the revalidate window expires still gets the old (stale) cached page instantly -- Next.js triggers a regeneration in the background at that point, and once the new HTML is ready, subsequent requests receive the fresh version. This stale-while-revalidate behavior means no visitor ever waits on a slow rebuild; they either get cached content or, shortly after, updated content, and the server load stays low because regeneration only happens occasionally rather than on every request.

🏏

Cricket analogy: It's like a scoreboard operator showing the last known score for a few more seconds while quickly confirming the actual update with the third umpire, rather than freezing the display blank while waiting.

tsx
// app/products/page.tsx -- time-based ISR
async function getProducts() {
  const res = await fetch('https://api.example.com/products', {
    next: { revalidate: 60 }, // regenerate at most once every 60 seconds
  });
  return res.json();
}

export default async function ProductsPage() {
  const products = await getProducts();
  return (
    <ul>
      {products.map((p: { id: string; name: string }) => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}

// app/api/revalidate/route.ts -- on-demand revalidation via a webhook
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const { path, secret } = await request.json();
  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ message: 'Invalid secret' }, { status: 401 });
  }
  revalidatePath(path);
  return NextResponse.json({ revalidated: true, now: Date.now() });
}

On-demand revalidation using revalidatePath() or revalidateTag() lets you invalidate a specific page or a group of cached fetches the instant your data actually changes -- for example, triggered by a CMS webhook when an editor publishes a new article -- instead of waiting for a fixed time window to expire.

New Paths at Runtime

ISR also handles paths that weren't included in generateStaticParams() at build time. When a visitor requests a dynamic route path that wasn't pre-rendered, Next.js can generate it on that first request and then cache the result as a static page for subsequent visitors, controlled by the dynamicParams export (true by default). This is especially useful for large catalogs, like an e-commerce site with tens of thousands of products, where pre-building every single page at build time would make deploys impractically slow.

🏏

Cricket analogy: It's like a stadium print shop only pre-printing scorecards for the marquee fixtures of the season, but printing a scorecard on demand the first time anyone asks for an obscure domestic warm-up match, then keeping that copy for future requests.

Setting dynamicParams to false will cause Next.js to return a 404 for any path not returned by generateStaticParams() at build time, instead of generating it on demand. Only do this deliberately when you want to strictly limit which paths exist.

  • ISR lets statically generated pages be regenerated after deployment without a full site rebuild.
  • Time-based revalidation via { next: { revalidate: N } } serves stale content instantly while regenerating in the background.
  • The stale-while-revalidate pattern means no visitor waits on a live rebuild; they get cached content, then fresher content soon after.
  • revalidatePath() and revalidateTag() enable on-demand revalidation triggered by events like CMS webhooks.
  • Paths not covered by generateStaticParams() can be generated on first request and cached, controlled by dynamicParams.
  • ISR is ideal for large catalogs where pre-building every page at build time would be impractically slow.
  • Setting dynamicParams to false restricts routes to only the paths explicitly pre-rendered at build time.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#NextJsStudyNotes#WebDevelopment#IncrementalStaticRegeneration#Incremental#Static#Regeneration#Problem#StudyNotes#SkillVeris