getStaticPaths
Dynamic Routes を使用するページから 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 の戻り値
getStaticPaths
関数は以下の 必須 プロパティを持つオブジェクトを返す必要があります:
paths
paths
キーはプリレンダリングするパスを決定します。例えば、Dynamic Routes を使用する 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
にはpostId
とcommentId
を含める必要があります。 - ページ名が
pages/[...slug]
のような キャッチオールルート を使用している場合、params
にはslug
(配列)を含める必要があります。この配列が['hello', 'world']
の場合、Next.js は/hello/world
でページを静的に生成します。 - ページが オプションのキャッチオールルート を使用している場合、ルートをレンダリングするには
null
、[]
、undefined
またはfalse
を使用します。例えば、pages/[[...slug]]
に対してslug: false
を指定すると、Next.js は/
ページを静的に生成します。
params
の文字列は 大文字と小文字を区別 し、パスが正しく生成されるように正規化することが理想的です。例えば、パラメータとして WoRLD
が返された場合、実際に訪問されたパスが WoRLD
でなければ world
や World
とは一致しません。
params
オブジェクトとは別に、i18n が設定されている 場合、生成されるパスのロケールを設定する locale
フィールドを返すことができます。
fallback: false
fallback
が false
の場合、getStaticPaths
で返されないパスは 404 ページ になります。
next build
を実行すると、Next.js は getStaticPaths
が fallback: false
を返したかどうかを確認し、getStaticPaths
で返されたパスのみ をビルドします。このオプションは、作成するパスが少ない場合や、新しいページデータが頻繁に追加されない場合に便利です。fallback: false
を設定している状態でさらにパスを追加する必要がある場合は、新しいパスを生成するために next build
を再度実行する必要があります。
以下の例では、pages/posts/[id].js
というページごとに1つのブログ投稿をプリレンダリングします。ブログ投稿のリストは CMS から取得され、getStaticPaths
によって返されます。次に、各ページに対して、getStaticProps
を使用して CMS から投稿データを取得します。
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
fallback
が true
の場合、getStaticProps
の動作は以下のように変わります:
getStaticPaths
から返されたパスは、ビルド時にgetStaticProps
によってHTML
にレンダリングされます。- ビルド時に生成されていないパスは、404 ページにはなりません。代わりに、Next.js はそのようなパスへの最初のリクエスト時にページの 「フォールバック」 バージョンを提供します。Google などのウェブクローラーにはフォールバックが提供されず、代わりに
fallback: 'blocking'
と同じように動作します。 fallback: true
のページにnext/link
またはnext/router
(クライアントサイド)を介してナビゲートすると、Next.js はフォールバックを提供せず、代わりにfallback: 'blocking'
と同じようにページが動作します。- バックグラウンドで、Next.js はリクエストされたパスの
HTML
とJSON
を静的に生成します。これにはgetStaticProps
の実行が含まれます。 - 完了すると、ブラウザは生成されたパスの
JSON
を受け取ります。これは、必要な props でページを自動的にレンダリングするために使用されます。ユーザーの視点では、ページがフォールバックページからフルページに切り替わります。 - 同時に、Next.js はこのパスをプリレンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時にプリレンダリングされた他のページと同様に、生成されたページを提供します。
Good to know:
output: 'export'
を使用する場合、fallback: true
はサポートされていません。
fallback: true
が役立つ場合
fallback: true
は、アプリにデータに依存する静的なページが非常に多い場合(非常に大規模な e コマースサイトなど)に役立ちます。すべての商品ページをプリレンダリングしたい場合、ビルドに非常に長い時間がかかります。
代わりに、ページの小さなサブセットを静的に生成し、残りには fallback: true
を使用できます。まだ生成されていないページがリクエストされると、ユーザーはローディングインジケーターやスケルトンコンポーネントを含むページを見ることになります。
その後すぐに、getStaticProps
が完了し、リクエストされたデータでページがレンダリングされます。これ以降、同じページをリクエストするすべてのユーザーには、静的にプリレンダリングされたページが提供されます。
これにより、ユーザーは常に高速な体験を得ながら、高速なビルドと静的生成の利点を維持できます。
fallback: true
は生成されたページを 更新 しません。そのためには、Incremental Static Regeneration を参照してください。
fallback: 'blocking'
fallback
が 'blocking'
の場合、getStaticPaths
で返されない新しいパスは、SSR と同様に(つまり ブロッキング として)HTML
の生成を待ち、その後将来のリクエストのためにキャッシュされるため、パスごとに1回だけ発生します。
getStaticProps
は以下のように動作します:
getStaticPaths
から返されたパスは、ビルド時にgetStaticProps
によってHTML
にレンダリングされます。- ビルド時に生成されていないパスは、404 ページにはなりません。代わりに、Next.js は最初のリクエスト時に SSR を実行し、生成された
HTML
を返します。 - 完了すると、ブラウザは生成されたパスの
HTML
を受け取ります。ユーザーの視点では、「ブラウザがページをリクエストしている」状態から「フルページが読み込まれた」状態に遷移します。ローディング/フォールバック状態のフラッシュはありません。 - 同時に、Next.js はこのパスをプリレンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時にプリレンダリングされた他のページと同様に、生成されたページを提供します。
fallback: 'blocking'
はデフォルトでは生成されたページを 更新 しません。生成されたページを更新するには、fallback: 'blocking'
と一緒に Incremental Static Regeneration を使用します。
Good to know:
output: 'export'
を使用する場合、fallback: 'blocking'
はサポートされていません。
フォールバックページ
ページの「フォールバック」バージョンでは:
- ページの props は空になります。
- router を使用すると、フォールバックがレンダリングされているかどうかを検出できます。
router.isFallback
がtrue
になります。
以下の例は isFallback
の使用を示しています:
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秒ごとに投稿を再生成
revalidate: 1,
}
}
export default Post
バージョン履歴
バージョン | 変更点 |
---|---|
v13.4.0 | App Router が安定版になり、generateStaticParams() を含む簡素化されたデータフェッチングが可能に |
v12.2.0 | On-Demand Incremental Static Regeneration が安定版に。 |
v12.1.0 | On-Demand Incremental Static Regeneration が追加(ベータ)。 |
v9.5.0 | Incremental Static Regeneration が安定版に。 |
v9.3.0 | getStaticPaths が導入。 |