Leveraging Incremental Static Regeneration to build static sites with dynamic content
What is Incremental Static Regeneration (ISR)?
In the context of Next.js, incremental static regeneration is a feature that allows you to create or update static pages after you’ve built your site. ISR enables you to use static-generation on a per-page basis, without needing to rebuild the entire site.
This is great because it allows your website to still show dynamic content while reaping all of the benefits of a statically generated site.
There are two approaches to ISR (or revalidation):
Background revalidation:
revalidating your pages at a set interval (i.e. 15 seconds, 1 minute, 1 hour, etc.). This is a great option if the frequency in which your data changes is known.
On-demand revalidation:
refers to the process of revalidating your website triggered by specific events, such as an update.
Before we go into specifics for each approach (background revalidation vs on-demand revalidation), there are some benefits of ISR I would like to highlight.
Benefits of adding ISR/revalidation to your site
1. benefits of statically-generated sites while staying scalable
retain the benefits of statically-generated sites while being able to scale at ease.
2. faster build times
Ideally, we would only want the pages that had their content change to be regenerated which is what ISR enables.
For example, a website with 100,000 pages would take a long time to build only if you were updating the content on 1 page.
3. better user experience
keeping your website’s content up-to-date in a timely and efficient manner is key for a high-end user experience for your customers.
Background revalidation approach explained
The first revalidation or ISR approach is the background revalidation approach.
As I’ve highlighted above, this approach is essentially updating your site at a specific time interval.
This gives the flexibility to configure your site for your specific use case; in other words, specific to your datasets.
For example, if I was developing a weather forecast application and I know that the weather gets updated at the start of every hour, it would make sense to set 1 hour for the revalidation time interval.
Implementation example:
On-demand Revalidation approach explained
The second ISR approach is on-demand revalidation. It’s a little bit more complicated, but the benefit is you will only revalidate your site when an event is triggered.
This benefit can easily be seen if your site integrates with a headless CMS like Sanity, Contentful or Payload.
Let’s say you have a site that displays your blog posts stored in Contentful. You realize you made a typo in your blog and make a quick edit.
This triggers Contentful to send an event to your site, letting us know that an update has been made and that we should regenerate the pages that care about this content.
In the code below, we see the implementation for that exact use case, but let me explain in more detail about our process here.
On-demand revalidation approach in-depth explanation
First, you’ll need a secret token only known by your Next.js application. It will be used to prevent unauthorized access to the revalidation API Route.
You can access your revalidation API route with the following structure:
https://<your-site.com>/api/revalidate?secret=token
Note: you’ll need to add this secret as an environment variable to your application.
Configure a webhook on your headless CMS platform
A webhook is a mechanism that allows real-time communication between different applications or services over the web via HTTP requests.
More information can be on Contentful’s documentation website: https://www.contentful.com/developers/docs/concepts/webhooks/
Configure your revalidation API Route on Next.js
Below are the changes to create your revalidate API route:
export default async function handler(req, res) {
// check if the secret exists and matches what we expect
if (
!req.headers.authorization ||
req.headers.authorization !== process.env.SECRET_TOKEN_REVALIDATION
) {
return res.status(401).json({ message: 'Invalid token' })
}
if (req.body.type === 'blogPost' && req.body.slug) {
try {
await revalidatePath('/')
await revalidatePath('/articles')
await revalidatePath(`/articles/${req.body.slug}`)
return res.json({ revalidated: true })
} catch (err) {
console.error(err)
return res.status(500).send('Error revalidating data')
}
}
}
const revalidatePath = async (path) => {
try {
await res.revalidate(path)
return res.json({ revalidated: true })
} catch (err) {
console.error(err)
return res.status(500).send('Error revalidating data')
}
}
In this example, this site is listening for any HTTP requests alerting of a blog post change on Contentful side via webhooks.
When a such a request does come through, it first checks for the secret token.
Then it checks for the type of update to be equal to “blogPost” which will tell the site which page to revalidate.
Finally, the site will take care of updating the right paths.
Conclusion
That was a lot of information! I suggest setting up an account with a headless CMS, creating a small template website using Next.js and try this whole revalidation process for yourself.
Thanks!