getStaticPaths

ダイナミックルートを使用するページから 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
}

getStaticPaths の戻り値

getStaticPaths 関数は以下の 必須 プロパティを持つオブジェクトを返す必要があります:

paths

paths キーはどのパスが事前レンダリングされるかを決定します。例えば、ダイナミックルートを使用する pages/posts/[id].js というページがあるとします。このページから getStaticPaths をエクスポートし、paths に対して以下を返す場合:

return {
  paths: [
    { params: { id: '1' }},
    {
      params: { id: '2' },
      // i18nが設定されている場合、パスのロケールも返すことができます
      locale: "en",
    },
  ],
  fallback: ...
}

Next.js は next build 時に pages/posts/[id].js のページコンポーネントを使用して /posts/1/posts/2 を静的に生成します。

params オブジェクトの値はページ名で使用されるパラメータと一致する必要があります:

  • ページ名が pages/posts/[postId]/[commentId] の場合、params には postIdcommentId を含める必要があります。
  • ページ名が pages/[...slug] のようなキャッチオールルートを使用している場合、params には slug(配列)を含める必要があります。この配列が ['hello', 'world'] の場合、Next.js は /hello/world でページを静的に生成します。
  • ページがオプショナルキャッチオールルートを使用している場合、ルートパスをレンダリングするには null[]undefined または false を使用します。例えば、pages/[[...slug]] に対して slug: false を指定すると、Next.js は / ページを静的に生成します。

params の文字列は 大文字と小文字を区別 し、パスが正しく生成されるように正規化することが理想的です。例えば、パラメータとして WoRLD が返された場合、実際に訪問されるパスが WoRLD でなければ一致せず、worldWorld とは一致しません。

params オブジェクトとは別に、i18nが設定されている場合、生成されるパスのロケールを設定する locale フィールドを返すことができます。

fallback: false

fallbackfalse の場合、getStaticPaths で返されないパスは 404ページ になります。

next build が実行されると、Next.js は getStaticPathsfallback: false を返したかどうかをチェックし、getStaticPaths で返されたパスのみをビルドします。このオプションは、作成するパスの数が少ない場合や、新しいページデータが頻繁に追加されない場合に便利です。より多くのパスを追加する必要があり、fallback: false を設定している場合、新しいパスを生成するために next build を再度実行する必要があります。

次の例では、pages/posts/[id].js というページごとに1つのブログ投稿を事前レンダリングします。ブログ投稿のリストはCMSから取得され、getStaticPaths によって返されます。その後、各ページに対して、getStaticProps を使用してCMSから投稿データを取得します。

pages/posts/[id].js
function Post({ post }) {
  // 投稿をレンダリング...
}

// この関数はビルド時に呼び出されます
export async function getStaticPaths() {
  // 外部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 }
}

// これもビルド時に呼び出されます
export async function getStaticProps({ params }) {
  // paramsには投稿の`id`が含まれます。
  // ルートが/posts/1の場合、params.idは1です
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // propsを介してページに投稿データを渡す
  return { props: { post } }
}

export default Post

fallback: true

fallbacktrue の場合、getStaticProps の動作は以下のように変化します:

  • getStaticPaths から返されたパスは、ビルド時に getStaticProps によって HTML にレンダリングされます。
  • ビルド時に生成されなかったパスは 404ページ になりません。代わりに、Next.js はそのようなパスへの最初のリクエストに対してページの「フォールバック」バージョンを提供します。Googleなどのウェブクローラーにはフォールバックが提供されず、代わりにfallback: 'blocking' と同じように動作します。
  • fallback: true のページが next/link または next/router(クライアントサイド)を介してナビゲートされると、Next.js はフォールバックを提供せず、ページはfallback: 'blocking' と同じように動作します。
  • バックグラウンドで、Next.js はリクエストされたパスの HTMLJSON を静的に生成します。これには getStaticProps の実行が含まれます。
  • 完了すると、ブラウザは生成されたパスの JSON を受け取ります。これは必要なpropsでページを自動的にレンダリングするために使用されます。ユーザーの視点では、ページはフォールバックページからフルページに切り替わります。
  • 同時に、Next.js はこのパスを事前レンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前レンダリングされた他のページと同様に、生成されたページを提供します。

知っておくと良い: fallback: trueoutput: 'export' を使用する場合にはサポートされていません。

fallback: true が役立つ場合

fallback: true は、アプリにデータに依存する非常に多くの静的ページ(非常に大きなeコマースサイトなど)がある場合に役立ちます。すべての商品ページを事前レンダリングしたい場合、ビルドに非常に長い時間がかかります。

代わりに、ページの小さなサブセットを静的に生成し、残りに fallback: true を使用することができます。まだ生成されていないページがリクエストされると、ユーザーはローディングインジケーターやスケルトンコンポーネントを含むページを見ることになります。

その後すぐに、getStaticProps が完了し、リクエストされたデータでページがレンダリングされます。これ以降、同じページをリクエストするすべての人は静的に事前レンダリングされたページを受け取ります。

これにより、ユーザーは常に高速な体験を得ながら、高速なビルドと静的生成の利点を維持できます。

fallback: true は生成されたページを 更新 しません。それにはIncremental Static Regeneration(増分的静的再生成)を参照してください。

fallback: 'blocking'

fallback'blocking' の場合、getStaticPaths で返されない新しいパスは、HTML が生成されるのを待ちます(SSRと同じため ブロッキング と呼ばれます)。その後、将来のリクエストのためにキャッシュされるため、パスごとに1回だけ発生します。

getStaticProps は以下のように動作します:

  • getStaticPaths から返されたパスは、ビルド時に getStaticProps によって HTML にレンダリングされます。
  • ビルド時に生成されなかったパスは 404ページ になりません。代わりに、Next.js は最初のリクエストでSSRを実行し、生成された HTML を返します。
  • 完了すると、ブラウザは生成されたパスの HTML を受け取ります。ユーザーの視点では、「ブラウザがページをリクエストしている」状態から「フルページがロードされた」状態に移行します。ローディング/フォールバック状態のフラッシュはありません。
  • 同時に、Next.js はこのパスを事前レンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前レンダリングされた他のページと同様に、生成されたページを提供します。

fallback: 'blocking' はデフォルトでは生成されたページを 更新 しません。生成されたページを更新するには、fallback: 'blocking' と一緒にIncremental Static Regeneration(増分的静的再生成)を使用します。

知っておくと良い: fallback: 'blocking'output: 'export' を使用する場合にはサポートされていません。

フォールバックページ

ページの「フォールバック」バージョンでは:

  • ページのpropsは空になります。
  • router を使用すると、フォールバックがレンダリングされているかどうかを検出できます。router.isFallbacktrue になります。

次の例は isFallback の使用を示しています:

pages/posts/[id].js
import { useRouter } from 'next/router'

function Post({ post }) {
  const router = useRouter()

  // ページがまだ生成されていない場合、getStaticProps()の実行が完了するまで
  // 最初にこれが表示されます
  if (router.isFallback) {
    return <div>Loading...</div>
  }

  // 投稿をレンダリング...
}

// この関数はビルド時に呼び出されます
export async function getStaticPaths() {
  return {
    // ビルド時に生成されるのは `/posts/1` と `/posts/2` のみ
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    // 追加ページの静的生成を有効にする
    // 例: `/posts/3`
    fallback: true,
  }
}

// これもビルド時に呼び出されます
export async function getStaticProps({ params }) {
  // paramsには投稿の`id`が含まれます。
  // ルートが/posts/1の場合、params.idは1です
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // propsを介してページに投稿データを渡す
  return {
    props: { post },
    // リクエストがある場合、最大1秒に1回投稿を再生成する
    revalidate: 1,
  }
}

export default Post

バージョン履歴

バージョン変更点
v13.4.0App Router が安定版になり、generateStaticParams() を含む簡素化されたデータ取得が可能に
v12.2.0オンデマンド増分的静的再生成 が安定版に
v12.1.0オンデマンド増分的静的再生成 が追加(ベータ)
v9.5.0増分的静的再生成 が安定版に
v9.3.0getStaticPaths が導入

On this page