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 はこのパスを事前レンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前レンダリングされた他のページと同様に、生成されたページを提供します
豆知識:
output: 'export'
を使用している場合、fallback: true
はサポートされていません。
fallback: true
が有用な場合
fallback: true
は、アプリがデータに依存する非常に多くの静的ページ(非常に大規模な e コマースサイトなど)を持っている場合に便利です。すべての商品ページを事前レンダリングしたい場合、ビルドに非常に長い時間がかかります。
代わりに、ページの小さなサブセットを静的に生成し、残りに fallback: true
を使用できます。まだ生成されていないページがリクエストされると、ユーザーはローディングインジケーターやスケルトンコンポーネントを含むページを見ることになります。
その後すぐに、getStaticProps
が完了し、リクエストされたデータでページがレンダリングされます。これ以降、同じページをリクエストするすべての人は、静的に事前レンダリングされたページを受け取ります。
これにより、ユーザーは常に高速な体験を得られながら、高速なビルドと静的生成の利点を維持できます。
fallback: true
は生成されたページを 更新 しません。更新するには Incremental Static Regeneration を参照してください。
fallback: 'blocking'
fallback
が 'blocking'
の場合、getStaticPaths
から返されない新しいパスは、SSR と同様に(そのため blocking)、HTML
が生成されるのを待ち、その後将来のリクエストのためにキャッシュされるため、パスごとに1回だけ発生します。
getStaticProps
は以下のように動作します:
getStaticPaths
から返されたパスは、getStaticProps
によってビルド時にHTML
にレンダリングされます- ビルド時に生成されなかったパスは 404 ページになりません。代わりに、Next.js は最初のリクエスト時に SSR を実行し、生成された
HTML
を返します - 完了すると、ブラウザは生成されたパスの
HTML
を受け取ります。ユーザーの視点では、「ブラウザがページをリクエスト中」から「ページが完全にロードされた」に遷移します。ローディング/フォールバック状態のフラッシュはありません - 同時に、Next.js はこのパスを事前レンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前レンダリングされた他のページと同様に、生成されたページを提供します
fallback: 'blocking'
はデフォルトで生成されたページを 更新 しません。生成されたページを更新するには、fallback: 'blocking'
と組み合わせて Incremental Static Regeneration を使用します。
豆知識:
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 が導入されました。 |