Introduction
Next.js allows you to create, update or render the content of a web page after you build your site. It also allows you to fetch the data on every load using functions. But we have to rebuild our application on every load to fetch the new data and load the scripts. You might have observed this on few websites too. Whenever you make some changes and reload the website, it takes a lot of time to update the data in the backend and display it to you. This makes data fetching and rendering complex, right? It might also be frustrating for the user to continue using that website. But do we have any strategy that doesn’t need us to rebuild the site every time?
Yes, we have a strategy, and that is called Incremental Static Regeneration. Let’s discuss the Incremental Static Regeneration strategy with a few examples.
Incremental Static Regeneration
Next.js released Static Site Generation long ago to fetch the data and render it to the web page. But it might be complex to use the SSG strategy for applications with a large codebase, as the build time increases linearly with the increasing web pages.

The above shows the relationship between build time and web pages. The build time increases linearly with the generation of static web pages, which might consume the user's time a lot. It is not possible to wait till the complete application is built. So to overcome this, Next.js introduced a new strategy called Incremental Static Regeneration.
Incremental Static Regeneration is a hybrid approach of Next.js that allows you to create or update the static content of the websites without a complete rebuild. The ISR generates static pages at run time instead of build time. We use the getStaticProps() method by specifying the revalidate key and setting it to 60. Setting the revalidate key to 60 will display the cached (hit) page for any requests to the page, after the initial request and before 60 seconds. You can set it to any value based on your requirements. We can make our own tradeoff using analytics, A/B testing, or other metrics at the build time. Let’s discuss the workflow/request flow for fetching data.
Data Fetching

Source
- Next.js defines the revalidation time per page according to the value set to revalidate variable.
- The cached page will be displayed on the initial request to the product page.
- The data required for the product is updated in the Content Management System(CMS).
- Any requests to the product page after the initial request and before 60 seconds will show the cached (hit) page.
- After 60 seconds, the subsequent request will still show the cached page. Next.js triggers regeneration of the static page in the background.
-
Once the page is generated successfully, Next.js will invalidate the cache and show the updated page. If the regeneration in the background fails, the old page remains unaltered.
export async function getStaticProps({params}) {
return {
props: {
Product: await getProductFromDatabase(params.id),
},
revalidate: 60,
}
}
This code works similarly to the process mentioned above the code.
Generating paths
Next.js defines the pages to be generated at the build-time based on the paths returned by the getStaticPaths() function. We use the fallback keyword here for the build. The fallback provides two options; blocked and true.
fallback: blocking - When a request is made to a page that is not generated yet, Next.js will server-render the page on the first request. The future requests will serve the static file from the cache.
export async function getStaticPaths() {
const product = await getProducts();
Const path = products.map((product) => ({
Params: { id: product.id },
}));
return { paths, fallback: ‘blocking’ };
}
fallback: true - When a request is made to a page that is not generated, Next.js will serve with a loading state on the first request. The page will be re-rendered with the new data and cached when the data is loaded completely.
export async function getStaticPaths() {
const product = await getProducts();
Const path = products.map((product) => ({
Params: { id: product.id },
}));
return { paths, fallback: ‘true’ };
}