Incremental Static Regeneration (ISR) Explained with Examples (2025 Guide)

Himmat Regar Jun 29, 2025, 10:48 PM
nextjs
Views 292
Blog Thumbnail

Static-site generation (SSG) gives you blazing-fast pages, but the moment your data changes you need a full rebuild… unless you use Incremental Static Regeneration (ISR). ISR lets a page stay static and quietly refresh in the background—no global rebuild, no slow users. Below is a 2025-focused guide that covers how ISR works in both the Pages Router and the newer App Router, shows on-demand revalidation, and finishes with best-practice tips.


1. What problem does ISR solve?

  • SSG → great performance, stale quickly.

  • SSR (or RSC “force-dynamic”) → always fresh, slower TTFB under load.

  • ISR sits between: serve a cached HTML file instantly, then — at a schedule you pick or on-demand — rebuild that single page in the background. Users never see the rebuild. nextjs.org


2. How ISR works under the hood

  1. First request after a build returns the pre-rendered HTML.

  2. Revalidation clock starts (e.g., 60 s).

  3. After the revalidation window expires, the next request triggers a background regeneration while still getting the stale HTML (stale-while-revalidate).

  4. Once the new HTML finishes, Vercel (or your host) swaps it in; future requests get the fresh page. nextjs.org


3. Using ISR in the Pages Router (/pages)

3.1 Timed revalidation (revalidate)

// pages/blog/[slug].tsx import { GetStaticProps, GetStaticPaths } from 'next'; export const getStaticPaths: GetStaticPaths = async () => { const slugs = await fetchCMSslugs(); return { paths: slugs.map(s => ({ params: { slug: s } })), fallback: 'blocking' }; }; export const getStaticProps: GetStaticProps = async ({ params }) => { const post = await fetchCMSpost(params!.slug as string); return { props: { post }, revalidate: 60, // seconds – regenerate at most once per minute }; }; export default function Blog({ post }) { /* … */ }

 

fallback: 'blocking' shows nothing until the first HTML is ready, avoiding an empty shell. ryanschiang.com

3.2 On-demand ISR (Build-free)

Need instant refresh (e.g., when an editor clicks “Publish”)? Hit an API route that calls res.revalidate('/blog/my-slug'):

// pages/api/revalidate.ts import type { NextApiRequest, NextApiResponse } from 'next'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { secret, path } = req.query; if (secret !== process.env.REVALIDATE_TOKEN) return res.status(401).json({ msg: 'Unauthorized' }); await res.revalidate(path as string); res.json({ revalidated: true }); }

 

Now a CMS webhook can POST to /api/revalidate?secret=...&path=/blog/my-slug. geeksforgeeks.org


4. Using ISR in the App Router (/app)

App-Router pages are static by default. You enable ISR with the revalidate option on fetch or by exporting a revalidate number.

4.1 Page-wide revalidate

// app/blog/[slug]/page.tsx export const revalidate = 120; // seconds export default async function BlogPage({ params }) { const post = await fetch(`https://cms.io/posts/${params.slug}`, { next: { revalidate }, // 👈 passes the same value to fetch cache }).then(r => r.json()); return <Article post={post} />; }

 

4.2 Tag-based on-demand ISR (Next 14)

Next 14 lets you group pages by cache tags and revalidate them together, without hard-coding paths:

// Fetch with a tag await fetch(url, { next: { tags: ['blog'] } }); // Revalidate all ‘blog’ pages from an action/route import { revalidateTag } from 'next/cache'; export async function POST() { revalidateTag('blog'); return Response.json({ ok: true }); }

 

Great for multi-locale or multi-tenant sites. dev.toemirbalic.com


5. ISR + Edge Functions (2025 status)

  • Pages Router ISR runs in Node serverless, not Edge.

  • App Router pages delivered from the Edge can still regenerate in a regional worker; the new HTML is globally propagated via Vercel’s cache. This “Edge-delivered, Node-regenerated” combo landed in early 2025. emirbalic.com


6. Practical patterns & gotchas

Pattern How to do it Caveat
Selective ISR Only pages with changing data get revalidate; the rest stay static. dev.to Don’t over-refresh — static wins for speed.
Preview drafts Use a preview cookie and force-dynamic route to bypass ISR for logged-in editors. Keep preview path secret.
Long tail pages fallback: 'blocking' + very long revalidate (e.g., 1 day) to avoid building thousands of pages up front. First hit is slower.
SEO Search bots that respect stale-while-revalidate will eventually see fresh HTML; set sensible revalidate (< 1 day). N/A
Edge + ISR Mark page export const runtime = 'edge' (App Router) and leave revalidate on fetch. No filesystem access in Edge runtime.

7. Example: Building a static product catalogue that updates hourly

// app/products/page.tsx import { fetchProducts } from '@/lib/api'; export const revalidate = 3600; // 1 hour export default async function Products() { const products = await fetchProducts({ next: { revalidate } }); return ( <ul className="grid gap-6 md:grid-cols-3"> {products.map(p => ( <li key={p.id} className="border p-4 rounded-xl"> <h3>{p.name}</h3> <p>{p.price} ₹</p> </li> ))} </ul> ); }

 

Hook up a webhook from your inventory system to revalidateTag('products') to force a refresh the moment a price changes.


8. Best practices for 2025

  1. Think per-page — give marketing landing pages long TTLs, while the blog gets 1–5 min.

  2. Protect revalidate tokens — keep them in env vars; rotate periodically.

  3. Log regeneration times — Vercel functions show rebuild duration; watch for API bottlenecks.

  4. Combine with drafts — editors preview via SSR, publish via on-demand ISR.

  5. Monitor cache hit-rate — use x-vercel-cache header to spot forced SSR.

  6. Edge where it helps — global low-latency read, Node for the heavy rebuild. github.com


9. Conclusion

ISR lets you enjoy the speed of static with the flexibility of dynamic content—a must-know technique for modern Next.js sites. Whether you’re on the older Pages Router or all-in on the App Router, the 2025 workflow is straightforward: set revalidate, tag strategically, and trigger rebuilds exactly when you need them. Happy regenerating! 🚀

 

Frequently Asked Questions (FAQ) — Incremental Static Regeneration (ISR)

# Question Quick Answer
1 What is Incremental Static Regeneration (ISR)? ISR is a Next.js feature that lets individual static pages regenerate in the background after a specified time or an on-demand trigger—so users get instant responses while content stays fresh.
2 How is ISR different from SSG and SSR? SSG: page is built once at deploy time. SSR/RSC dynamic: page is built on every request. ISR: page is served from the cache like SSG, but selectively rebuilt on a schedule or webhook; it’s a hybrid of both worlds.
3 Does ISR work in both the Pages Router and App Router? Yes. In the Pages Router you return revalidate from getStaticProps; in the App Router you export export const revalidate = <seconds> or pass { next: { revalidate } } to fetch().
4 What values can I give revalidate? Any positive integer (seconds). revalidate: 60 means “rebuild at most once per minute.” Use false (or omit) for fully static, 0 for always-dynamic.
5 What happens during regeneration? After the timeout, the next request receives the stale HTML, and a background rebuild starts. Once finished, the new HTML replaces the old in the cache; subsequent visitors see the fresh page.
6 How do I trigger ISR on demand? Pages Router: call res.revalidate('/path') inside an API Route. App Router: import revalidatePath('/path') or revalidateTag('tag') in a Route Handler or Server Action. Hook that to a CMS webhook.
7 What’s the difference between revalidatePath and revalidateTag? revalidatePath('/blog/my-post') refreshes one URL. revalidateTag('blog') refreshes every page whose fetch() call was tagged with next: { tags: ['blog'] }. Tags are new in Next 14+ for bulk revalidation.
8 Do I need to enable Vercel-specific settings for ISR? No. ISR works out of the box on Vercel. For other hosts you need a file-system-compatible cache or the official Next.js standalone server; most major providers now support it.
9 Can ISR pages run on the Edge Runtime? App-Router pages can be served from edge regions (export const runtime = 'edge'). The regeneration itself still happens in a regional worker; the fresh HTML is then propagated worldwide.
10 How do I preview drafts without breaking ISR? Serve preview mode with a cookie and bypass caching (export const dynamic = 'force-dynamic' in the App Router or fallback: 'blocking' with auth). Only editors with the cookie see unpublished content.
11 What’s the cost of setting revalidate too low? Very low values (<15 s) can cause frequent rebuilds, hitting function limits and API quotas. Tune the interval to match how often your data actually changes.
12 How do I know if a request is served from cache or revalidated? Check the response header x-vercel-cache (or your host’s equivalent). Values: HIT, STALE, MISS, REVALIDATED.
13 Can I combine ISR with incremental static exports (next export)? No. next export outputs purely static HTML and disables all runtime features—use a Node or Edge deployment to get ISR.
14 Does ISR affect SEO? No negative impact. Search engines receive HTML like any static site. Because rebuilds are atomic, crawlers always get a complete document—never half-rendered content.
15 What are common pitfalls? Forgetting to set fallback: 'blocking' (Pages Router) can flash a loading state; using Node-only APIs in an Edge page; sending confidential revalidate tokens in query strings—keep them in env vars or headers.

 

Comments

Please login to leave a comment.

No comments yet.

Related Posts

nextjs-api-routes-backend-functionality
281 viewsnextjs
Himmat Regar Jun 29, 2025, 5:03 PM

How to Use API Routes in Next.js for Backend Functional...

multi-language-website-nextjs-i18n
166 viewsnextjs
Himmat Regar Jun 30, 2025, 5:14 PM

Building a Multi-Language Website with Next.js 15 & Mod...

nextjs-explained-beginners-guide-2025
374 viewsnextjs
Himmat Regar Jun 27, 2025, 10:12 AM

Next.js Explained: A 2025 Beginner’s Guide to the React...

nextjs-file-based-routing-guide
369 viewsnextjs
Himmat Regar Jun 27, 2025, 11:23 AM

Understanding File-Based Routing in Next.js

nextjs-tailwind-css-perfect-ui-pairing
161 viewsnextjs
Himmat Regar Jun 30, 2025, 5:25 PM

Next.js 15 + Tailwind CSS 4: The Perfect UI Pairing

image-optimization-nextjs-everything-you-should-know
287 viewsnextjs
Himmat Regar Jun 29, 2025, 5:20 PM

Image Optimization in Next.js: Everything You Should Kn...

nextjs-vs-react-differences
353 viewsnextjs
Himmat Regar Jun 27, 2025, 11:09 AM

Next.js vs React: What’s the Difference and When to Use...

why-every-developer-should-learn-typescript-in-2025
30 viewsnextjs
Himmat Regar Jul 3, 2025, 5:56 PM

Why Every Developer Should Learn TypeScript in 2025

nextjs-markdown-blog-tutorial
375 viewsnextjs
Himmat Regar Jun 27, 2025, 10:18 AM

How to Build Your First Blog Using Next.js and Markdown

what-is-a-blog
183 viewsMarketing
Himmat Kumar Mar 12, 2025, 7:06 AM

What is a Blog? Understanding Its Purpose, Structure, a...