Incremental Static Regeneration

Learn how to implement Incremental Static Regeneration (ISR) for optimal performance and freshness.

Overview

Incremental Static Regeneration (ISR) allows you to create or update static pages after you've built your site. This combines the benefits of static generation with the ability to handle dynamic content.

Implementation

  1. 1

    Basic ISR Setup

    Configure a page with ISR:

    // pages/posts/[id].tsx
    export async function getStaticProps({ params }) {
      const post = await fetchPost(params.id);
    
      return {
        props: { post },
        revalidate: 60, // Regenerate page every 60 seconds
      };
    }
    
    export async function getStaticPaths() {
      return {
        paths: [],
        fallback: 'blocking',
      };
    }
  2. 2

    On-demand Revalidation

    Implement on-demand revalidation:

    // pages/api/revalidate.ts
    export default async function handler(req, res) {
      try {
        await res.revalidate('/path-to-revalidate');
        return res.json({ revalidated: true });
      } catch (err) {
        return res.status(500).send('Error revalidating');
      }
    }

Features and Benefits

ISR is a practical middle ground: you get the speed of static pages and the ability to keep content fresh over time.

Pages are served statically from the edge, providing optimal performance.

Advanced Configuration

Once ISR works, tuning is mostly about cache behavior and choosing the right revalidation strategy.

Good to know

Configure ISR based on your content update patterns and traffic requirements.

Custom Cache Control

export async function getStaticProps() {
  return {
    props: {
      data: await fetchData(),
    },
    revalidate: 60,
    headers: {
      'Cache-Control': 's-maxage=1, stale-while-revalidate=59',
    },
  };
}

Conditional Revalidation

export async function getStaticProps({ params }) {
  const data = await fetchData(params.id);

  return {
    props: { data },
    revalidate: data.type === 'frequent' ? 60 : 3600,
  };
}

Best Practices

These defaults work well for most content-driven pages.

  • Choose appropriate revalidation intervals
  • Implement fallback pages for better UX
  • Use on-demand revalidation when needed
  • Monitor revalidation patterns
  • Consider cache strategies

Common Patterns

Hybrid Approach

export async function getStaticProps({ params }) {
  const data = await fetchData(params.id);

  if (data.type === 'dynamic') {
    return {
      props: { data },
      revalidate: 1, // Frequent updates
    };
  }

  return {
    props: { data },
    revalidate: false, // Truly static
  };
}

Next Steps

Use ISR when the page can be slightly stale. If you need always-fresh data, prefer SSR.