Part 46: Ensuring Consistency with Incremental Static Regeneration in Next.js
[Pages] Data Fetching

In our recent exploration of Next.js, we implemented a ProductPage that dynamically generates pages for individual products. This dynamic routing is similar to our previous PostPage example in a blog setup. However, one crucial aspect we need to address is ensuring our pages remain up-to-date when product data changes in the CMS. This is where Incremental Static Regeneration (ISR) becomes essential.
Understanding Incremental Static Regeneration
ISR allows Next.js to update static pages after the initial build, without requiring a full rebuild. This feature is incredibly useful for content that changes frequently, such as product details. Let's dive into how we can apply ISR to our ProductPage to ensure it displays the latest product data.
Initial Setup of ISR in the HomePage
Previously, we configured the HomePage to use ISR. This was done by setting the revalidate option in getStaticProps. Here’s a quick reminder of how we set it:
// pages/index.js
export async function getStaticProps() {
const products = await getProducts();
return {
props: { products },
revalidate: 30, // seconds
};
}Testing Without ISR on ProductPage
Initially, our ProductPage did not utilize ISR. Let’s explore what happens without it:
We build and start our application in production mode.
We change the product data in the CMS, for instance, adding "Updated!" to a product title.
After reloading the HomePage, we see the new data after the ISR interval (30 seconds) has passed.
However, reloading the
ProductPagestill shows the old title, as it wasn't set to regenerate.
This inconsistency can be confusing for users, as one page shows updated data while another does not.
Implementing ISR on ProductPage
To solve this, we need to apply the revalidate setting to our ProductPage as well. Here's how you can update the code:
// pages/products/[id].js
import Head from 'next/head';
import Title from '../../components/Title';
import { getProduct, getProducts } from '../../lib/products';
export async function getStaticPaths() {
const products = await getProducts();
return {
paths: products.map((product) => ({
params: { id: product.id.toString() },
})),
fallback: false,
};
}
export async function getStaticProps({ params: { id } }) {
const product = await getProduct(id);
return {
props: { product },
revalidate: 30, // seconds
};
}
function ProductPage({ product }) {
console.log('[ProductPage] render:', product);
return (
<>
<Head>
<title>{product.title} - Next Shop</title>
</Head>
<main className="px-6 py-4">
<Title>{product.title}</Title>
<p>{product.description}</p>
</main>
</>
);
}
export default ProductPage;Explanation
Revalidate Option: By adding
revalidate: 30, we tell Next.js to regenerate theProductPageevery 30 seconds if there are requests for that page.Console Log: A console log is added to verify when the
ProductPagegets re-rendered, aiding in visual confirmation during testing.
Re-testing the Application
Rebuild the application and start it in production mode.
Make changes in the CMS, such as updating a product title.
Reload the pages to observe the changes. Both HomePage and
ProductPageshould now reflect the updated data consistently after the ISR interval.
Conclusion
By utilizing ISR across both HomePage and ProductPage, we ensure that our application remains consistent and up-to-date, providing a seamless experience for users. It's crucial to apply ISR to all relevant pages displaying the same data to avoid discrepancies and maintain user trust. Keep experimenting with ISR settings to optimize your application's performance and responsiveness!
Last updated