All about Next.js ISR and how to implement it

Published on March 19, 2025

Nextjs Incremental Static Regeneration (ISR)

Next.js Incremental Static Regeneration (ISR) provides a balance between performance and content freshness. Before ISR was introduced in Next.js version 9.5 in 2020, developers interested in balancing these had to choose between static site generation (SSG), which gave fast performance but required a full rebuild and deployment every time content changed, and server-side rendering (SSR), which ensured fresh content but had slower performance due to pages being regenerated on each request. 

Next.js ISR gives you the best of both worlds, making it an ideal solution for content-heavy sites such as ecommerce platforms, blogs, and news websites. In this article, we explain what Next.js ISR is, its benefits, and how to implement it.

What is Next.js ISR?

Next.js ISR is a hybrid rendering strategy for Next.js projects that combines static site generation (SSG) with incremental updates.

SSG is a rendering strategy that pre-renders pages at build time and then serves them as static HTML, meaning you don't need to wait for either the browser or the server to render the pages on request. While this is great for performance, it does require a full rebuild and redeployment to update your content. If your content updates regularly and you don't update your pages regularly, your content becomes stale and less effective. 

ISR enables static pages to be updated after deployment without rebuilding the entire site. It does this by regenerating the page in the background at specified intervals, ensuring fresh content while maintaining SSG's performance benefits.

The difference between Next.js ISR and other Next.js rendering methods

How ISR works

ISR can be used whenever you have static pages that are made from templates with content generated from an external source like an API or database.

Like SSG, pages are pre-rendered at build time and served as static HTML; however, the pages can also be regenerated in the background at specified intervals.

Let's follow a series of requests to a particular page to understand exactly how ISR works:

  1. At build time, the page is statically generated (like in SSG) and stored as HTML in a cache. This cache is typically stored on a content delivery network (CDN) such as Vercel's Edge Network or Netlify.

  2. A user requests the page and Next.js instantly serves them the cached version.

  3. After some time, the revalidation time period expires (this is an interval that you as the developer can specify). 

  4. Some time later, another user may request the page.

  5. On every request, Next.js checks if the revalidation time has passed. Since it has now passed, the user still receives the cached version immediately, but their request triggers a background regeneration of the page.

  6. Once the new version of the page has been generated, the cache is updated with the latest version of the page.

  7. Subsequent requests for the page will now receive the updated version.

How ISR works

How to implement Next.js Incremental Static Regeneration

As Next.js ISR is a way to add content freshness to static site generators, this guide assumes you're already using SSG. Also, for ISR to work properly, you'll need to host your site on a compatible platform (like Vercel Edge Network or Netlify). It will not work on platforms that only serve static files, such as GitHub Pages. Vercel Edge Network is a great match for Next.js ISR — Next.js was built by Vercel, so ISR works out of the box with it. With Netlify, it still works but may need some manual configuration.

Here, we'll show you how to use Next.js ISR to do both time-based and immediate revalidation

Time-based revalidation is when you define a time-based interval (e.g., 60 seconds), and after this time, the page is regenerated. This is useful if you have content that needs updating periodically but which doesn’t need updating instantly (like blog posts or product listings).

Immediate revalidation will immediately regenerate the page whenever you ask it to. You can create an immediate revalidation endpoint and call it whenever you update a large amount of data. This is needed for sites where real-time updates are critical (like stock prices, event availability, or dashboards with frequently changing data). Constant revalidation is very costly though, so sometimes you'll need to choose an affordable balance between time-based and immediate revalidation.

Time-based revalidation in Next.js ISR

To implement time-based revalidation, you must set a revalidate property inside the getStaticProps function. This will cause the page to be regenerated at regular intervals.

Immediate revalidation in Next.js ISR

To implement immediate revalidation, create an API route that's responsible for doing the revalidation, and call this endpoint any time you finish updating some of the data that makes up your page. You can use a webhook to automatically call that endpoint any time your data has been updated, and then within that endpoint, use res.revalidate(path)to invalidate the cached version of the page, which manually triggers the page to regenerate.

For example, if you were using Contentful to manage a blog site, you could add a webhook in the Contentful app, give it the webhook URL https://yourdomain.com/pages/api/revalidate.js, add triggers for when an entry has been published or unpublished, and customize the payload to be something like:

Then, you could create the API route /pages/api/revalidate.js, extract the path of the page that you want to revalidate from the request, and call res.revalidate on that path in the handler function. Due to the way that Next.js API routes work, the handler will be called whenever a POST request is sent to /api/revalidate — so you should set up your code to make such a request whenever content is updated.

Common issues with ISR and how to fix them

1. Your page is still serving old content after the revalidation time has passed.

Cause: Your CDN may be holding onto content for longer than is needed, so even though ISR regenerates the page, it's not getting updated in all edge locations immediately.

Solution: Use res.revalidate to manually force the revalidation, or manually purge your CDN cache.

2. Revalidation works in development but not production.

Cause: Your hosting provider does not support ISR.

Solution: Make sure you're on a platform that supports ISR out of the box — e.g., Vercel. If you're self-hosting, ensure you deploy your app with next start instead of next export. The next export command is for purely static sites with no backend code, and ISR won't work with that.

3. ISR is not working on dynamic routes (404 errors).

Cause: ISR expects pages to be pre-rendered before doing updates, but the problem is, some dynamic pages haven't been pre-rendered at build time (since they didn't exist at build time).

Solution: Add fallback: "blocking" to getStaticPaths. This will temporarily block these dynamic pages from being loaded until they have been pre-rendered in the background.

Best practices for implementing ISR

Choose appropriate revalidation intervals: The ideal revalidation interval should balance cost, performance, and UX. Manually revalidating using res.revalidate() will give the best UX; however, if you use this on every page load, you'll miss out on the performance (and cost) benefits of ISR. Spend some time considering which pages require immediate revalidation and which can afford to use time-based validation — and for those pages that will use time-based validation, decide on an appropriate revalidation interval that's suitable for your performance and content freshness needs.

Optimize data fetching for ISR pages: Enhance your API response times by caching API requests when it makes sense to.

Monitor and analyze your ISR performance: Use logging and monitoring to measure the success of using ISR (and to detect issues).

Using Next.js ISR with Contentful

For those using Contentful, you can use webhooks with your Next.js ISR setup to trigger instant regeneration whenever your content in Contentful has been updated. You simply need to set up a webhook and point it to your /pages/api/revalidate.js route.

To make this work, go to Contentful → Settings → Webhooks and create a new webhook, which you need to set to trigger on publish and unpublish events:

  • URL: https://yourdomain.com/api/revalidate?secret=your-secret-key

  • Method: POST

  • Payload: Ensure it includes entry.fields.slug

Finally, update your API route handler to handle the webhook secret and to use the entry.fields.slug field to set the path of the page that needs to be revalidated with res.revalidate.

If you'd like to get started using Contentful with Next.js, check out our Contentful Next.js starter guide and sign up to Contentful today.

Subscribe for updates

Build better digital experiences with Contentful updates direct to your inbox.

Meet the authors

David Fateh

David Fateh

Software Engineer

Contentful

David Fateh is a software engineer with a penchant for web development. He helped build the Contentful App Framework and now works with developers that want to take advantage of it.

Related articles

Find out everything you need to know about vector databases, including their architecture, use cases, and how to integrate and leverage them in your apps.
Guides

What are vector databases and should you be using one?

June 20, 2024

When companies need better ways to maintain a consistent digital experience across multiple web pages, apps and devices, design systems are the solution.
Guides

What is a design system?

June 20, 2023

Avoid these common mistakes when using JavaScript’s global object, variables, and functions. This article shows you how to use JavaScript globals properly.
Guides

What is the global object in JavaScript? A practical guide for developers

January 16, 2017

Contentful Logo 2.5 Dark

Ready to start building?

Put everything you learned into action. Create and publish your content with Contentful — no credit card required.

Get started