On demand ISR usage example

Next.js allows you to create or update static pages after you’ve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, without needing to rebuild the entire site. With ISR, you can retain the benefits of static while scaling to millions of pages.

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}

Would not be great if we only regenerate this page when our data changes? Since Next.js 12.2.0 we can do that using the res.revalidate function in our API Routes.

export default async function handler(_req, res) {
  // Revalidate our '/' path
  await res.revalidate('/')

  // Return a response to confirm everything went ok
  return res.json({revalidated: true})
}

Calling this API route will revalidate our content on demand, not just purging the old content but running getStaticProps again, generating new content and caching it for the next user, allowing us to increment or even remove the time revalidation in our pages. On demand revalidation might be useful for commerce providers, webhooks, bots, etc. That might fire when our content has been changed.

Calling revalidate will run getStaticProps for that path synchronously so we can await it. If you need to revalidate multiple paths you will need to run revalidate once for every path:

export default async function handler(_req, res) {
  // Get paths to revalidate
  const paths = await api.pathsToRevalidate()

  // Revalidate every path
  await Promise.all(paths.map(res.revalidate))

  // Return a response to confirm everything went ok
  return res.json({revalidated: true})
}

We have to also keep in mind that revalidating a path will run the getStaticProps serverless function for that specific path, which will count for our function execution time. Also awaiting for every path to revalidate on our API route will make it run longer and that will also count for our function execution time.

Depending on you application needs you might not need to wait for that validation to end and you can do a fire and forget request for those paths:

export default async function handler(_req, res) {
  // Get paths to revalidate
  const paths = await api.pathsToRevalidate()

  // Revalidate every path without awaiting
  paths.forEach(res.revalidate)

  // Return a response to confirm everything went ok
  return res.json({revalidated: true})
}

Demo

This demo was generated on 15:17:23 GMT+0000 (Coordinated Universal Time), product prices and stock might have changed since then. You can try revalidating this content.

Click here to revalidate:

Or call the revalidate endpoint:

/api/revalidate

Technology

Vercedge headphones V3

Edge level quality

Not available

Jewelry

Versun super sun glasses

Embellished square sunglasses

$6.00

Technology

Verseconds watch

Time with colors and widgets

Not available

Sports

Bikecel magic bike

Moving at the speed of edge

$33.00

Remember to always be careful when exposing endpoints as they may be vulnerable to DDOS attacks. You can request a key, token, etc. to protect the endpoint from unwanted requests.