コンテンツへスキップ
APIリファレンス関数generateStaticParams

generateStaticParams

generateStaticParams関数は、動的ルートセグメントと組み合わせて使用することで、リクエスト時ではなくビルド時にルートを静的に生成することができます。

app/blog/[slug]/page.js
// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}
 
// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default async function Page({ params }) {
  const { slug } = await params
  // ...
}

知っておくと良い点:

  • dynamicParamsセグメント設定オプションを使用して、generateStaticParamsで生成されなかった動的セグメントにアクセスしたときの動作を制御できます。
  • ランタイム時にパスを再検証(ISR)するには、generateStaticParamsから空の配列を返すか、export const dynamic = 'force-static'を使用する必要があります。
  • next dev中は、ルートに移動するとgenerateStaticParamsが呼び出されます。
  • next build中は、対応するレイアウトまたはページが生成される前にgenerateStaticParamsが実行されます。
  • 再検証(ISR)中は、generateStaticParamsは再度呼び出されません。
  • generateStaticParamsは、Pages Router のgetStaticPaths関数を置き換えます。

パラメータ

options.params (オプション)

ルート内の複数の動的セグメントがgenerateStaticParamsを使用する場合、子generateStaticParams関数は、親が生成する各paramsセットに対して1回実行されます。

paramsオブジェクトには、親generateStaticParamsからの設定済みのparamsが含まれており、これを使用して子セグメントのparamsを生成できます。

戻り値

generateStaticParamsは、各オブジェクトが単一のルートの設定済みの動的セグメントを表すオブジェクトの配列を返す必要があります。

  • オブジェクト内の各プロパティは、ルートに設定する動的セグメントです。
  • プロパティ名はセグメントの名前であり、プロパティの値はそのセグメントに設定する値です。
ルート例generateStaticParamsの戻り値の型
/product/[id]{ id: string }[]
/products/[category]/[product]{ category: string, product: string }[]
/products/[...slug]{ slug: string[] }[]

単一動的セグメント

app/product/[id]/page.tsx
export function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }, { id: '3' }]
}
 
// Three versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default async function Page({ params }: { params: { id: string } }) {
  const { id } = await params
  // ...
}

複数動的セグメント

app/products/[category]/[product]/page.tsx
export function generateStaticParams() {
  return [
    { category: 'a', product: '1' },
    { category: 'b', product: '2' },
    { category: 'c', product: '3' },
  ]
}
 
// Three versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
// - /products/a/1
// - /products/b/2
// - /products/c/3
export default async function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  const { category, product } = await params
  // ...
}

キャッチオール動的セグメント

app/product/[...slug]/page.tsx
export function generateStaticParams() {
  return [{ slug: ['a', '1'] }, { slug: ['b', '2'] }, { slug: ['c', '3'] }]
}
 
// Three versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default async function Page({ params }: { params: { slug: string[] } }) {
  const { slug } = await params
  // ...
}

静的レンダリング

ビルド時にすべてのパスを静的にレンダリングする

ビルド時にすべてのパスを静的にレンダリングするには、`generateStaticParams` にパスの完全なリストを提供します。

app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}

ビルド時におけるパスの部分集合

ビルド時にパスの部分集合を静的にレンダリングし、残りは初回アクセス時にランタイムでレンダリングするには、パスの部分リストを返します。

app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  // Render the first 10 posts at build time
  return posts.slice(0, 10).map((post) => ({
    slug: post.slug,
  }))
}

`generateStaticParams` で生成されなかった動的セグメントがアクセスされた場合の動作は、`dynamicParams` セグメント設定オプションを使用して制御できます。

app/blog/[slug]/page.js
// All posts besides the top 10 will be a 404
export const dynamicParams = false
 
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
  const topPosts = posts.slice(0, 10)
 
  return topPosts.map((post) => ({
    slug: post.slug,
  }))
}

ランタイムでのすべてのパス

すべてのパスを初回アクセス時に静的にレンダリングするには、空の配列を返すか(ビルド時にパスはレンダリングされません)、`export const dynamic = 'force-static'` を使用します。

app/blog/[slug]/page.js
export async function generateStaticParams() {
  return []
}

**重要:** 空であっても、`generateStaticParams` からは常に配列を返す必要があります。 そうしないと、ルートは動的にレンダリングされます。

app/changelog/[slug]/page.js
export const dynamic = 'force-static'

指定されていないパスのレンダリングを無効にする

指定されていないパスがランタイムで静的にレンダリングされないようにするには、ルートセグメントに `export const dynamicParams = false` オプションを追加します。 この設定オプションを使用すると、`generateStaticParams` で提供されたパスのみが提供され、指定されていないルートは 404 エラーを返すか、(キャッチオールルートの場合)一致するルートにフォールバックします。

ルートにおける複数の動的セグメント

現在のレイアウトまたはページの上にある動的セグメントのパラメータを生成できますが、**下には生成できません**。 例えば、`app/products/[category]/[product]` ルートの場合

  • `app/products/[category]/[product]/page.js` は `[category]` と `[product]` の**両方**のパラメータを生成できます。
  • `app/products/[category]/layout.js` は `[category]` のパラメータのみ生成できます。

複数の動的セグメントを持つルートのパラメータ生成には、2 つの方法があります。

ボトムアップ方式のパラメータ生成

子ルートセグメントから複数の動的セグメントを生成します。

app/products/[category]/[product]/page.tsx
// Generate segments for both [category] and [product]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())
 
  return products.map((product) => ({
    category: product.category.slug,
    product: product.id,
  }))
}
 
export default function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  // ...
}

トップダウン方式のパラメータ生成

まず親セグメントを生成し、その結果を使用して子セグメントを生成します。

app/products/[category]/layout.tsx
// Generate segments for [category]
export async function generateStaticParams() {
  const products = await fetch('https://.../products').then((res) => res.json())
 
  return products.map((product) => ({
    category: product.category.slug,
  }))
}
 
export default function Layout({ params }: { params: { category: string } }) {
  // ...
}

子ルートセグメントの `generateStaticParams` 関数は、親 `generateStaticParams` が生成する各セグメントに対して1回実行されます。

子 `generateStaticParams` 関数は、親 `generateStaticParams` 関数から返された `params` を使用して、独自のセグメントを動的に生成できます。

app/products/[category]/[product]/page.tsx
// Generate segments for [product] using the `params` passed from
// the parent segment's `generateStaticParams` function
export async function generateStaticParams({
  params: { category },
}: {
  params: { category: string }
}) {
  const products = await fetch(
    `https://.../products?category=${category}`
  ).then((res) => res.json())
 
  return products.map((product) => ({
    product: product.id,
  }))
}
 
export default function Page({
  params,
}: {
  params: { category: string; product: string }
}) {
  // ...
}

**重要:** `fetch` リクエストは、すべての `generate` 接頭辞付き関数、レイアウト、ページ、サーバーコンポーネント間で同じデータに対して自動的にメモ化されます。 `fetch` が利用できない場合は、React の`cache` を使用できます

バージョン履歴

バージョン変更内容
v13.0.0`generateStaticParams` が導入されました。