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',
},
}, // See the "paths" section below
],
fallback: true, // false or "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' },
// with i18n configured the locale for the path can be returned as well
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`オブジェクトとは別に、i18nが設定されている場合、生成されるパスのロケールを設定する`locale`フィールドを返すことができます。
`params`文字列は**大文字と小文字が区別されます**。パスが正しく生成されるように、理想的には正規化されるべきです。例えば、パラメータに`WoRLD`が返された場合、`world`や`World`ではなく、実際のパスが`WoRLD`の場合にのみ一致するようになります。
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 }) {
// Render post...
}
// This function gets called at build time
export async function getStaticPaths() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false }
}
// This also gets called at build time
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via 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
を受信します。これは、必要なプロパティを使用してページを自動的にレンダリングするために使用されます。ユーザーの視点からは、ページはフォールバックページから完全なページに切り替わります。 - 同時に、Next.js はこのパスを事前にレンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前にレンダリングされた他のページと同様に、生成されたページを提供します。
知っておくと良い点:
output: 'export'
を使用する場合、fallback: true
はサポートされていません。
fallback: true
はいつ役立ちますか?
アプリケーションにデータに依存する非常に多くの静的ページがある場合(非常に大規模なECサイトなど)、fallback: true
は役立ちます。すべての商品ページを事前にレンダリングする場合、ビルドに非常に長い時間がかかります。
代わりに、ページの小さなサブセットを静的に生成し、残りのページには fallback: true
を使用できます。まだ生成されていないページをユーザーがリクエストすると、ローディングインジケーターまたはスケルトンコンポーネントが表示されます。
その後すぐに、getStaticProps
が完了し、リクエストされたデータを使用してページがレンダリングされます。それ以降、同じページをリクエストするすべての人が、静的に事前にレンダリングされたページを取得します。
これにより、高速なビルドと静的生成の利点を維持しながら、ユーザーは常に高速なエクスペリエンスを得ることができます。
fallback: true
は生成されたページを更新しません。それについては、Incremental Static Regeneration をご覧ください。
fallback: 'blocking'
fallback
が 'blocking'
の場合、getStaticPaths
によって返されない新しいパスは、HTML
が生成されるまで待機し(そのためブロッキング)、その後、将来のリクエストのためにキャッシュされるため、パスごとに一度だけ発生します。
getStaticProps
は次のように動作します。
getStaticPaths
から返されたパスは、ビルド時にgetStaticProps
によってHTML
にレンダリングされます。- ビルド時に生成されなかったパスは、404 ページになりません。代わりに、Next.js は最初のリクエストで SSR を実行し、生成された
HTML
を返します。 - 完了すると、ブラウザは生成されたパスの
HTML
を受信します。ユーザーの視点からは、「ブラウザがページをリクエスト中」から「完全なページがロードされました」に遷移します。ローディング/フォールバック状態の点滅はありません。 - 同時に、Next.js はこのパスを事前にレンダリングされたページのリストに追加します。同じパスへの後続のリクエストは、ビルド時に事前にレンダリングされた他のページと同様に、生成されたページを提供します。
fallback: 'blocking'
はデフォルトでは生成されたページを更新しません。生成されたページを更新するには、fallback: 'blocking'
と組み合わせて Incremental Static Regeneration を使用します。
知っておくと良い点:
output: 'export'
を使用する場合、fallback: 'blocking'
はサポートされていません。
フォールバックページ
ページの「フォールバック」バージョンでは
- ページのプロパティは空になります。
- router を使用して、フォールバックがレンダリングされているかどうかを検出できます。
router.isFallback
はtrue
になります。
次の例では、isFallback
の使用方法を示しています。
import { useRouter } from 'next/router'
function Post({ post }) {
const router = useRouter()
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
return <div>Loading...</div>
}
// Render post...
}
// This function gets called at build time
export async function getStaticPaths() {
return {
// Only `/posts/1` and `/posts/2` are generated at build time
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
// Enable statically generating additional pages
// For example: `/posts/3`
fallback: true,
}
}
// This also gets called at build time
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via props
return {
props: { post },
// Re-generate the post at most once per second
// if a request comes in
revalidate: 1,
}
}
export default Post
バージョン履歴
バージョン | 変更点 |
---|---|
v13.4.0 | App Router が、generateStaticParams() を含む簡素化されたデータフェッチと共に安定版になりました。 |
v12.2.0 | オンデマンドインクリメンタル静的再生 が安定版になりました。 |
v12.1.0 | オンデマンドインクリメンタル静的再生 が追加されました(ベータ版)。 |
v9.5.0 | 安定版 Incremental Static Regeneration |
v9.3.0 | getStaticPaths が導入されました。 |
これは役に立ちましたか?