Lang x Lang

Incremental Static Regeneration (ISR)

Examples

Next.js は、サイトの構築後に静的ページを作成または更新することができます。Incremental Static Regeneration(ISR)を利用すると、サイト全体を再構築する必要なく、ページごとに静的生成を行うことができます。ISR を使用すれば、何百万ものページにスケールアップしながら静的の恩恵を享受することができます。

Good to know: 現在、edge runtimeは ISR と互換性がありませんが、cache-control header を手動で設定することにより、stale-while-revalidateを利用することができます。

ISR を使うには、getStaticPropsrevalidateプロップを追加します:

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

// 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
  };
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }));

  // We'll pre-render only these paths at build time.
  // { fallback: 'blocking' } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: "blocking" };
}

export default Blog;

request が、build 時に事前にレンダリングされたページに対して行われた場合、最初にキャッシュされたページが表示されます。

  • 初回の request とその後の 10 秒以内にページに対する全てのリクエストもキャッシュされ、瞬時に処理されます。
  • 10 秒の window の後でも、次の next request は依然としてキャッシュされた( stale )ページを表示します
  • Next.js はバックグラウンドでページの再生成をトリガーします。
  • ページが正常に生成されると、Next.js は cache を無効にし、更新されたページを表示します。バックグラウンドでの再生成が失敗した場合でも、古いページは変わらずそのままになります。

未生成の path に対して request があると、 Next.js は初回の request でページをサーバーレンダリングします。将来のリクエストは、 cache から静的ファイルを提供します。Vercel 上の ISR は、グローバルに cache を保持し、ロールバックを処理します

Good to know: あなたの上流データプロバイダが default で cache を有効化しているかどうか確認してください。 cache を無効化しなければならない場合があります(例:useCdn: false)。そうでないと、再検証が新しいデータを引っ張ってくることができず、 ISR cache を更新することができません。 キャッシングは、request されたエンドポイントで CDN(Cache-Control header が戻るとき)で発生する可能性があります。

On-Demand Revalidation

revalidateの時間を60に設定すると、すべての訪問者は 1 分間、同じ生成された version のサイトを見ることになります。cache を無効にする唯一の方法は、1 分が経過した後にそのページを訪れる人からです。

v12.2.0から始まり、Next.js cache は、特定のページの Next.js キャッシュを手動でパージするためのオンデマンドの Incremental Static Regeneration をサポートします。これにより、以下の場合にサイトの更新が容易になります:

  • ヘッドレス CMS からのコンテントが作成または更新されました
  • E コマースの metadata の変更(価格、 description 、カテゴリー、レビューなど)

getStaticPropsの中では、オンデマンド再検証を使用するためにrevalidateを指定する必要はありません。もしrevalidateが省略された場合、Next.js はfalse(再検証なし)の defaultvalue を使用し、revalidate()が呼び出されたときにのみ、ページを再検証します。

Good to know: Middlewareは、オンデマンドの ISR リクエストで実行されません。代わりに、再確認したい path に対してrevalidate()を呼び出します。例えば、pages/blog/[slug].jsがあり、/post-1から/blog/post-1への rewrite がある場合、res.revalidate('/blog/post-1')を呼び出す必要があります。

オンデマンド再検証の使用

まず、Next.js app だけが知っている secret トークンを作成します。この secret は、API Route への不正なアクセスを防ぐために使用されます。次の URL 構造を使用して route(手動または webhook で)にアクセスできます。

Terminal
https://<your-site.com>/api/revalidate?secret=<token>

次に、secret をアプリケーションのEnvironment Variableとして追加します。最後に、リバリデーションの API Route を作成します:

pages/api/revalidate.js
export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }

  try {
    // this should be the actual path not a rewritten path
    // e.g. for "/blog/[slug]" this should be "/blog/post-1"
    await res.revalidate('/path-to-revalidate')
    return res.json({ revalidated: true })
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating')
  }
}

弊社のデモをご覧ください 。オンデマンド再検証がどのように動作するかを確認し、フィードバックを提供してください。

development 中のオンデマンド ISR のテスト

next devでローシーで動作する場合、getStaticPropsはすべての request で呼び出されます。ISR の設定が正しいかを確認するには、 production build を作成し、 production server: を start する必要があります。

Terminal
next build
next start

その後、静的ページが正常に再検証されたことを確認できます。

Error handling and revalidation

getStaticPropsでバックグラウンド再生を処理中に error が発生した場合、または手動で error をスローした場合でも、最後に正常に生成されたページが表示され続けます。次の next の request では、 Next.js がgetStaticPropsを再試行します。

export async function getStaticProps() {
  // If this request throws an uncaught error, Next.js will
  // not invalidate the currently shown page and
  // retry getStaticProps on the next request.
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  if (!res.ok) {
    // If there is a server error, you might want to
    // throw an error instead of returning so that the cache is not updated
    // until the next successful request.
    throw new Error(`Failed to fetch posts, received status ${res.status}`);
  }

  // If the request was successful, return the posts
  // and revalidate every 10 seconds.
  return {
    props: {
      posts,
    },
    revalidate: 10,
  };
}

Self-hosting ISR

Incremental Static Regeneration (ISR)は、next startを使用すると、自己ホスト型の Next.js サイトで手間なく動作します。

self-hosting Next.jsについてさらに学ぶ。

Version History

VersionChanges
v14.1.0カスタム cacheHandler は安定しています。
v12.2.0オンデマンド ISR は安定しています
v12.1.0オンデマンド ISR 追加(ベータ版)。
v12.0.0ボットに対応した ISR fallback が追加されました。
v9.5.0ベース Path が追加されました。

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use