Skip to main content

Incremental Static Regeneration

Incremental Static Regeneration (ISR) that allows you to generate a static page when the page is first visited, rather than generating a static copy at build time. It's a mix of SSG and SSR.

Introduction

Incremental Static Regeneration (ISR) allows you to create or update content without redeploying your site. ISR has three main benefits for developers: better performance, improved security, and faster build times. This is a really handy feature as it allows you to reduce your build time, but still benefit from having a cache of a page generated so future visitors will have a faster response time.

ISR app

Comparison with Others

SSRCSRSSGISR
Each page will initiate a request to App Server, where it dynamically renders and serves full HTML for that page. Since it requests and renders the page each time user requests, page serve time is more than a CSR application.SEO benefits because of rendering at server sideCSR receiving all of the content from the HTML document, content is rendered in the browser using the client-side JavaScript library. The browser does not make a new request to the server when a new page is loaded.Search engine rankings may be negatively impacted as the content is not rendered until the page is loaded on the browserTo avoid the rendering in each request, why don't we generate those files in the build time, so that we can instantly serve the pages when user requests it.Incremental Static Regeneration (ISR) is the same as Static Site Generation except that content can be rebuilt when the page is updated.

Pros & Cons

  • Pros

    • Better Performance: Static pages can be consistently fast by caching generated pages in every region and persisting files into durable storage
    • Improved Security: ISR Render Functions are used to generate pages and do not have access to the incoming request, which prevents accidental caching of user data for increased security
    • Faster Builds: Pages can defer generation on request or through an API instead of during the build, helping keep build times fast as your application grows
  • Cons

When to use ISR

  • Increase API calls It's crucial to consider how many API calls ISR could generate. If you set the revalidate property to 5 seconds, your API endpoint will be called every 5 seconds. Depending on API quotas, pricing, and capacity, this might be worth exploring.
  • Stale Data for ISR Initiator I'd want to emphasize that the first individual that visits your website and starts ISR will continue to receive the old, stale data. The content will be updated for the second person that visits.
  • Not Beneficial If You Already have Quick Build Time Build times may not be as important if your application takes simply a few minutes or fewer to develop. Performing a full build ensures that your new content appears on every page.

Examples

  • Incremental Static Regeneration works well for e-commerce, marketing pages, blog posts, ad-backed media, and more.
    • E-commerce Next.js Commerce is an all-in-one starter kit for high-performance e-commerce sites.
    • GitHub Reactions React to the original GitHub issue and watch ISR update the statically generated landing page.
    • Static Tweets This project deploys in 30 seconds, but can statically generate 500M tweets on-demand using ISR.

Code Example Snippets (if beneficial)

Here's a working example that puts into practice everything we learned. Our demo will randomly pick a public API using this awesome API in three ways: ISR, SSG, and SSR.

Let's start by building our page component. Thanks to Next.js, we can write it once and use it for all methods as long as we provide the same props:

import{ useRouter }from'next/router';

exportdefaultfunctionPage(props){

const{ isFallback }= useRouter();

if(isFallback){

return\<\>\</\>;

}

return\<div\>

\<h1\>{props.name}\</h1\>

\<p\>{props.description}\</p\>

\</div\>

}

Our props object contains the name of the public API and its description. We display them using a header and a paragraph element accordingly. One caveat is that we have to check for the ISR fallback mode, as mentioned above.

During this mode, the props might not be defined, so we have to take care of it. I return here an empty element for simplicity's sake, but a better approach is to show loaders or a skeleton page.

Our page is ready, and now we can fetch some data from the API. We will use node-fetch for this purpose, as all the calls are made outside the browser, so the browser's inbuilt fetch function is not available.

import fetch from'node-fetch';

exportasyncfunctiongetRandomAPI(){

const res =await fetch('https://api.publicapis.org/random');

const json =await res.json();

return{

name: json.entries[0].API,

description: json.entries[0].Description,

};

}

We call the API endpoint that returns a random public API and organize it into a better structure that includes the name and description, just like our props object.

The essential elements are ready, and all that's left to do is create the actual Next.js pages — one for every rendering method.

SSR:

importPagefrom'../Page';

import{ getRandomAPI }from'../publicApis';

exportdefaultPage;

exportasyncfunctiongetServerSideProps(){

const props =await getRandomAPI();

return{ props };

}

The only difference is the function name. There's also another fundamental difference, and it's that this time, the function is called on every request, rather than just at build time.

SSG:

importPagefrom'../Page';

import{ getRandomAPI }from'../publicApis';

exportdefaultPage;

exportasyncfunctiongetStaticProps(){

const props =await getRandomAPI();

return{ props };

}

Every static page should export a getStaticProps function. The function is invoked at build time, and the returned props are forwarded to the React component as props. In this example, we call our remote API endpoint and return its response.

ISR:

importPagefrom'../Page';

import{ getRandomAPI }from'../publicApis';

exportdefaultPage;

exportasyncfunctiongetStaticProps(){

const props =await getRandomAPI();

return{ props,revalidate:30};

}

Using ISR is much like SSG with an additional revalidate property. This new property states how often to revalidate the page (in seconds):

The SSR version uses getServerSideProps instead of getStaticProps. The ISR version sets the revalidation period to 30s.