Back to Blog
Lesson 41 of the Next.js: Build Full-Stack Apps with the App Router course
Next.jsAugust 28, 20264 min read

Incremental Static Regeneration (ISR) in Next.js

Learn how to use Incremental Static Regeneration (ISR) to update static pages in the background. Keep your blog content fresh without full site rebuilds.

Next.jsISRCachingPerformanceWeb Development

Previously in this course, we covered Mastering Static Site Generation (SSG) in Next.js, where we learned how to pre-render pages at build time. While SSG is incredibly fast, it has one major limitation: if your data changes, you have to trigger a full site rebuild to see those updates.

In this lesson, we are adding Incremental Static Regeneration (ISR) to our toolkit. ISR allows us to update static pages after the site has been deployed, in the background, without requiring a full rebuild.

Understanding ISR from First Principles

In a traditional SSG setup, your pages are "frozen" once the build completes. If you fix a typo in a blog post or update a comment, that change won't appear until the next deployment.

ISR solves this by introducing a "revalidation" period. Instead of the page being static forever, you tell Next.js: "This page is valid for X seconds."

When a user visits the page:

  1. If the time elapsed is less than X seconds: Next.js serves the cached, static version instantly.
  2. If the time elapsed is greater than X seconds: Next.js serves the stale version to the user, but simultaneously triggers a background rebuild of that specific page. Once the background process finishes, the new version is cached and served to the next visitor.

This gives you the performance of static files with the flexibility of dynamic content.

Implementing Time-based Revalidation

Businessperson writing on a document at a wooden desk, with focus on hands and pen.

To implement ISR in the App Router, we use the revalidate segment config option. This is a simple constant you export from your page.js or layout.js files.

In our project, let's update our individual blog post pages to revalidate every hour (3600 seconds). Open your dynamic route file (e.g., app/blog/[slug]/page.js):

JAVASCRIPT
// app/blog/[slug]/page.js

export const revalidate = 3600; // Revalidate at most every hour

export default async function BlogPostPage({ params }) {
  const post = await getPostBySlug(params.slug);
  
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

By setting this constant, Next.js automatically manages the cache for this route. If you want to force a refresh for a specific user action (like an admin dashboard update), you can pair this with Revalidating Data with revalidatePath in Next.js.

Cache Management Strategies

Understanding how your data is cached is critical for performance. Here is a breakdown of the different caching behaviors in Next.js:

StrategyBehaviorUse Case
Static (Default)Rendered once at build time.Blog posts, marketing pages.
ISRStatic, but refreshes in background.Content that changes occasionally.
DynamicRendered on every request.Real-time dashboards, user profiles.

Hands-on Exercise: Implementing ISR

  1. Open your app/blog/[slug]/page.js.
  2. Add export const revalidate = 60; to the top of the file.
  3. Start your dev server.
  4. Modify a blog post in your database (or mock data source).
  5. Refresh the page. You will initially see the "stale" data, but after a second request, the new data will appear.

Common Pitfalls

  • Setting revalidate = 0: While this is often used to disable caching, remember that it makes the page dynamic. Use this sparingly, as it increases load on your database.
  • Over-revalidating: If you set a very short revalidation time (e.g., 1 second) on a high-traffic page, you might unintentionally trigger a massive number of background builds, hitting your database limits.
  • Confusing revalidate with revalidatePath: Remember that revalidate is a time-based passive strategy, while revalidatePath is an event-based active strategy. Often, you'll want to use both, as discussed in Next.js App Router: Implementing Tag-based ISR Invalidation.

FAQ

Does ISR work on every hosting provider? ISR is a feature of the Next.js framework. While it works best on Vercel, it is supported on other platforms that support the Next.js cache handler.

What happens if the background revalidation fails? Next.js will continue to serve the old (stale) version of the page until the next successful revalidation attempt. Your users are never left with a broken page.

Can I set revalidation for the whole site? Yes, you can set export const revalidate = 3600 in your app/layout.js to set a default revalidation period for all pages in your application.

Recap

ISR is the "best of both worlds" approach. By defining a revalidate constant, you allow your site to remain lightning-fast while ensuring content stays current. For more granular control over your cache, consider how this fits into Caching Fundamentals: Cache-Aside Patterns and Performance.

Up next: We will learn how to design custom error interfaces to handle production failures gracefully in "Customizing Error Pages."

Similar Posts