getStaticPaths
Dynamic Routesを使用するページから getStaticPathsという関数をエクスポートする場合、 Next.js は getStaticPathsで指定されたすべての paths を静的に事前にレンダリングします。
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
}
export async function getStaticPaths() {
return {
paths: [
{
params: {
name: 'next.js',
},
}, // See the "paths" section below
],
fallback: true, // false or "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 return values
getStaticPaths関数は、以下の必須プロパティを持つ object を返す必要があります:
paths
pathsキーは、どの paths が事前にレンダリングされるかを決定します。例えば、pages/posts/[id].jsという名前のDynamic Routesを使用するページがあるとします。あなたがこのページからgetStaticPathsを export して、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 はpages/posts/[id].jsのページ component を使用して、next buildの間に/posts/1と/posts/2を静的に生成します。
各paramsの object の value は、ページ名で使用されているパラメータと一致しなければなりません:
- ページの名前が
pages/posts/[postId]/[commentId]である場合、paramsはpostIdとcommentIdを含むべきです。 - ページ名がcatch-all routesを使う場合、つまり
pages/[...slug]のような形式である場合、paramsはslug(配列)を含むべきです。この配列が['hello', 'world']である場合、Next.js は/hello/worldでページを静的に生成します。 - ページがオプショナルな catch-all routeを使用している場合は、
null、[]、undefined、またはfalseを用いて最もルートの route を render してください。例えば、pages/[[...slug]]に対してslug: falseを提供すると、 Next.js はページ/を静的に生成します。
params 文字列は大文字と小文字を区別します。理想的には、 paths が正しく生成されるように正規化するべきです。例えば、Worldがパラメータに対して返された場合、それはWoRLDが訪れた実際の path と一致するだけで、WoRLDやworldでは一致しません。
paramsの object とは別に、i18n が設定されている場合、生成される path の locale を設定するlocaleフィールドが返されることがあります。
fallback: false
fallbackがfalseである場合、getStaticPathsによって返されない paths は404 ページが出力されます。
next buildが実行されるとき、Next.js はgetStaticPathsがfallback: falseを返したかどうかを確認し、その場合、getStaticPathsによって返された paths のみを build します。このオプションは、作成する paths の number が少ない、または新しいページデータが頻繁に追加されない場合に便利です。もし新たな paths を追加する必要があると分かり、そしてfallback: falseを持っている場合、新しい paths を生成できるように再度next buildを実行する必要があります。
次の例では、pages/posts/[id].jsという 1 ページごとに 1 つのブログの post を事前レンダリングします。ブログの投稿のリストは CMS からフェッチされ、getStaticPathsによって返されます。その後、各ページは CMS から post データをgetStaticPropsを使用してフェッチします。
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
Examples
fallbackがtrueの場合、getStaticPropsの動作は以下のように変わります:
getStaticPathsから返される paths は、getStaticPropsによってHTMLへと build 時にレンダリングされます。- まだ build 時に生成されていない paths は、404 ページが表示されない結果になります。その代わり、Next.js はそのような path への最初の request で、ページのfallbackversion を提供します。Google などの Web クローラは、fallback が提供されることはなく、代わりに path は、
fallback: 'blocking'のように動作します。 fallback: trueのページがnext/linkやnext/router(Client 側)を通じて移動した場合、Next.js は fallback を提供しない代わりに、ページはfallback: 'blocking'のように振る舞います。- バックグラウンドで、Next.js は要求された path の
HTMLとJSONを静的に生成します。これにはgetStaticPropsの実行が含まれます。 - 完了すると、ブラウザは生成された path の
JSONを受信します。これは、必要な props でページを自動的に render するために使用されます。ユーザーの視点からすると、ページは fallback ページからフルページに切り替わります。 - 同時に、Next.js はこの path を事前レンダリングされたページのリストに追加します。同じ path への後続の Request は、build 時に事前レンダリングされた他のページと同様に、生成されたページを提供します。
Good to know:
fallback: trueは、output: 'export'を使用する場合にはサポートされていません。
fallback: trueはいつ役立つのでしょうか?
fallback: trueは、あなたの app がデータに依存する静的ページの number が非常に多い場合(大規模な e-commerce サイトなど)に役立ちます。すべての商品ページを事前にレンダリングしたい場合、build には非常に長い時間がかかります。
それよりも、ページの小さな部分を静的に生成し、残りは fallback: true を使用することができます。まだ生成されていないページを誰かが要求したとき、ユーザーは loading インジケーターや component スケルトンと共にそのページを見ることになります。
その後すぐに、getStaticPropsが完了し、Request されたデータでページがレンダリングされます。これからは、同じページを Request する全ての人が静的に事前レンダリングされたページを取得します。
これにより、ユーザーは常に高速な体験を持つことが保証される一方で、高速な build と Static Generation の利点が保持されます。
fallback: trueは生成されたページを更新しません、それについてはIncremental Static Regenerationを参照してみてください。
fallback: 'blocking'
fallbackが'blocking'の場合、新しい paths は、getStaticPathsによって返されないため、HTMLが生成されるのを待ち、それは SSR (それがblockingである理由)と同じで、その後、将来のリクエストのためにキャッシュされます。そのため、 path ごとに一度だけ起こります。
getStaticPropsは以下のように動作します:
getStaticPathsから返される paths は、getStaticPropsによってHTMLへと build 時にレンダリングされます。- build 時に生成されていない paths は 404 ページを生じません。代わりに、Next.js は初回の request で SSR を行い、生成された
HTMLを返します。 - 完了時には、ブラウザは生成された path の
HTMLを受け取ります。ユーザーから見ると、"ブラウザがページを要求している"から"フルページがロードされた"へと遷移します。Loading/フォールバックの状態が一瞬表示されることはありません。 - 同時に、Next.js はこの path を事前レンダリングされたページのリストに追加します。同じ path への後続の Request は、build 時に事前レンダリングされた他のページと同様に、生成されたページを提供します。
fallback: 'blocking'は default では生成されたページを更新しません。生成されたページを更新するためには、fallback: 'blocking'と組み合わせてIncremental Static Regenerationを使用してください。
Good to know:
fallback: 'blocking'はoutput: 'export'を使用する際にはサポートされていません。
Fallback ページ
ページの fallback の version では:
- そのページの props は empty になります。
- router を使用すると、fallback がレンダリングされているかどうかを検出できます。
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
Version History
| Version | Changes |
|---|---|
v13.4.0 | App Routerは、generateStaticParams()を含む単純化されたデータフェッチで安定しています |
v12.2.0 | オンデマンド Incremental Static Regenerationは安定しています。 |
v12.1.0 | オンデマンド Incremental Static Regeneration追加(ベータ版)。 |
v9.5.0 | 安定版 Incremental Static Regeneration |
v9.3.0 | getStaticPathsが導入されました。 |