getStaticPaths

ページが ダイナミックルート を使用しており、かつ getStaticProps を利用している場合、静的に生成するパスのリストを定義する必要があります。

ダイナミックルートを使用するページから getStaticPaths 関数(静的サイト生成)をエクスポートすると、Next.js は getStaticPaths で指定されたすべてのパスを静的にプリレンダリングします。

import type {
  InferGetStaticPropsType,
  GetStaticProps,
  GetStaticPaths,
} from 'next'

type Repo = {
  name: string
  stargazers_count: number
}

export const getStaticPaths = (async () => {
  return {
    paths: [
      {
        params: {
          name: 'next.js',
        },
      }, // 以下の "paths" セクションを参照
    ],
    fallback: true, // false または "blocking"
  }
}) satisfies GetStaticPaths

export const getStaticProps = (async (context) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}) satisfies GetStaticProps<{
  repo: Repo
}>

export default function Page({
  repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
  return repo.stargazers_count
}
export async function getStaticPaths() {
  return {
    paths: [
      {
        params: {
          name: 'next.js',
        },
      }, // 以下の "paths" セクションを参照
    ],
    fallback: true, // false または "blocking"
  }
}

export async function getStaticProps() {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}

export default function Page({ repo }) {
  return repo.stargazers_count
}

getStaticPaths API リファレンス では、getStaticPaths で使用できるすべてのパラメーターとプロパティを網羅しています。

getStaticPaths を使用するタイミング

以下の場合に getStaticPaths を使用するべきです(ダイナミックルートを使用するページを静的にプリレンダリングする場合):

  • データがヘッドレス CMS から取得される場合
  • データがデータベースから取得される場合
  • データがファイルシステムから取得される場合
  • データが公開キャッシュ可能な場合(ユーザー固有でない場合)
  • ページが SEO のためにプリレンダリングされ、かつ高速である必要がある場合 — getStaticPropsHTMLJSON ファイルを生成し、どちらも CDN でキャッシュ可能でパフォーマンス向上に寄与します

getStaticPaths の実行タイミング

getStaticPaths は本番環境ではビルド時にのみ実行され、ランタイム中には呼び出されません。このツール を使用して、getStaticPaths 内のコードがクライアントサイドバンドルから削除されていることを確認できます。

getStaticProps の実行と getStaticPaths の関係

  • getStaticProps はビルド時に返された paths に対して next build 中に実行されます
  • fallback: true を使用時、getStaticProps はバックグラウンドで実行されます
  • fallback: blocking を使用時、getStaticProps は初期レンダリング前に呼び出されます

getStaticPaths の使用場所

  • getStaticPaths必ず getStaticProps と一緒に使用する必要があります
  • getServerSideProps と一緒に getStaticPaths使用できません
  • getStaticProps も使用する ダイナミックルート から getStaticPaths をエクスポートできます
  • 非ページファイル(例: components フォルダ)から getStaticPathsエクスポートできません
  • getStaticPaths はスタンドアロン関数としてエクスポートする必要があり、ページコンポーネントのプロパティとしてはエクスポートできません

開発環境でのリクエストごとの実行

開発環境 (next dev) では、getStaticPaths はリクエストごとに呼び出されます。

オンデマンドでのパス生成

getStaticPaths では、fallback を使用してオンデマンドで生成する代わりに、ビルド時にどのページを生成するかを制御できます。ビルド時に多くのページを生成すると、ビルドが遅くなります。

paths に空の配列を返すことで、すべてのページの生成をオンデマンドに延期できます。これは特に Next.js アプリケーションを複数の環境にデプロイする場合に便利です。例えば、プレビュー環境ではすべてのページをオンデマンドで生成することで(本番ビルドでは生成せず)、より高速なビルドを実現できます。これは数百/数千の静的ページがあるサイトに有効です。

pages/posts/[id].js
export async function getStaticPaths() {
  // プレビュー環境などで true の場合
  // 静的ページをプリレンダリングせず
  // (ビルドは高速化、但し初期ページ読み込みは低速化)
  if (process.env.SKIP_BUILD_STATIC_GENERATION) {
    return {
      paths: [],
      fallback: 'blocking',
    }
  }

  // 外部APIエンドポイントを呼び出して投稿を取得
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 投稿に基づいてプリレンダリングするパスを取得
  // 本番環境ではすべてのページをプリレンダリング
  // (ビルドは低速化、但し初期ページ読み込みは高速化)
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // { fallback: false } は他のルートを404にする
  return { paths, fallback: false }
}