getStaticProps
ページからgetStaticProps
(静的サイト生成)という関数をエクスポートすると、Next.jsはgetStaticProps
が返すpropsを使用して、ビルド時にこのページをプリレンダリングします。
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
type Repo = {
name: string
stargazers_count: number
}
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
}
レンダリングタイプに関わらず、任意の
props
はページコンポーネントに渡され、初期HTMLでクライアント側から表示できることに注意してください。これは、ページを正しくハイドレーションできるようにするためです。props
に、クライアントで利用できるべきではない機密情報を渡さないように注意してください。
getStaticProps
APIリファレンスでは、getStaticProps
で使用できるすべてのパラメータとpropsについて説明しています。
getStaticPropsはいつ使用すべきか
以下の場合にgetStaticProps
を使用する必要があります:
- ページのレンダリングに必要なデータが、ユーザーのリクエスト前のビルド時に利用可能
- データがヘッドレスCMSから取得される
- ページをSEOのために事前レンダリングし、非常に高速にする必要がある —
getStaticProps
はHTML
とJSON
ファイルを生成し、パフォーマンスのためにCDNでキャッシュできる - データを公開キャッシュ可能(ユーザー固有ではない)。この条件は、特定の状況でミドルウェアを使用してパスを書き換えることで回避できます。
getStaticPropsはいつ実行されるか
getStaticProps
は常にサーバー上で実行され、クライアント上では実行されません。getStaticProps
内に記述されたコードがクライアント側バンドルから削除されることは、このツールで検証できます。
getStaticProps
は常にnext build
中に実行されますgetStaticProps
はfallback: true
を使用する際にバックグラウンドで実行されますgetStaticProps
はfallback: blocking
を使用する際の初期レンダリング前に呼び出されますgetStaticProps
はrevalidate
を使用する際にバックグラウンドで実行されますgetStaticProps
はrevalidate()
を使用する際にオンデマンドでバックグラウンドに実行されます
インクリメンタル静的再生成と組み合わせると、getStaticProps
はキャッシュされたページが再検証されている間にバックグラウンドで実行され、更新されたページがブラウザに提供されます。
getStaticProps
は静的HTMLを生成するため、受信リクエスト(クエリパラメータやHTTPヘッダーなど)にアクセスできません。ページのリクエストにアクセスする必要がある場合は、getStaticProps
に加えてミドルウェアの使用を検討してください。
getStaticPropsを使用してCMSからデータを取得する
以下の例は、CMSからブログ投稿のリストを取得する方法を示しています。
// postsはgetStaticProps()によってビルド時に設定されます
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
// この関数はサーバー側のビルド時に呼び出されます。
// クライアント側では呼び出されないため、
// データベースへの直接クエリも可能です。
export async function getStaticProps() {
// 投稿を取得するための外部APIエンドポイントを呼び出します。
// 任意のデータ取得ライブラリを使用できます
const res = await fetch('https://.../posts')
const posts = await res.json()
// { props: { posts } }を返すことで、
// Blogコンポーネントはビルド時に`posts`をpropsとして受け取ります
return {
props: {
posts,
},
}
}
getStaticProps
APIリファレンスでは、getStaticProps
で使用できるすべてのパラメータとpropsについて説明しています。
サーバー側のコードを直接記述する
getStaticProps
はサーバー側でのみ実行されるため、クライアント側では実行されません。ブラウザ用のJSバンドルにも含まれないため、データベースクエリをブラウザに送信することなく直接記述できます。
つまり、getStaticProps
から外部ソースからデータを取得するAPIルートをフェッチする代わりに、getStaticProps
内にサーバー側のコードを直接記述できます。
以下の例を見てみましょう。CMSからデータを取得するAPIルートが使用されています。そのAPIルートがgetStaticProps
から直接呼び出されます。これにより追加の呼び出しが発生し、パフォーマンスが低下します。代わりに、CMSからデータを取得するロジックをlib/
ディレクトリを使用して共有できます。その後、getStaticProps
と共有できます。
// 以下の関数は
// getStaticPropsとAPIルートで
// `lib/`ディレクトリから共有されます
export async function loadPosts() {
// 投稿を取得するための外部APIエンドポイントを呼び出す
const res = await fetch('https://.../posts/')
const data = await res.json()
return data
}
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
// この関数はサーバー側でのみ実行されます
export async function getStaticProps() {
// `/api`ルートをフェッチする代わりに、
// 同じ関数を`getStaticProps`から直接呼び出せます
const posts = await loadPosts()
// 返されたPropsはページコンポーネントに渡されます
return { props: { posts } }
}
あるいは、データ取得にAPIルートを使用しない場合、fetch()
APIをgetStaticProps
内でデータを取得するために直接使用できます。
クライアント側バンドルからNext.jsが何を削除するかを確認するには、next-code-elimination toolを使用できます。
HTMLとJSONの両方を静的に生成
getStaticProps
を持つページがビルド時に事前レンダリングされると、ページHTMLファイルに加えて、getStaticProps
の実行結果を含むJSONファイルがNext.jsによって生成されます。
このJSONファイルは、next/link
またはnext/router
によるクライアント側のルーティングで使用されます。getStaticProps
を使用して事前レンダリングされたページに移動すると、Next.jsはこのJSONファイル(ビルド時に事前計算された)をフェッチし、ページコンポーネントのpropsとして使用します。つまり、クライアント側のページ遷移ではgetStaticProps
は呼び出されず、エクスポートされたJSONのみが使用されます。
インクリメンタル静的生成を使用する場合、getStaticProps
はクライアント側のナビゲーションに必要なJSONを生成するためにバックグラウンドで実行されます。同じページに対して複数のリクエストが行われるように見える場合がありますが、これは意図的なものであり、エンドユーザーのパフォーマンスには影響しません。
getStaticPropsはどこで使用できるか
getStaticProps
はページからのみエクスポートできます。_app
、_document
、_error
などの非ページファイルからはエクスポートできません。
この制限の理由の1つは、Reactがページをレンダリングする前にすべての必要なデータを持っている必要があるためです。
また、getStaticProps
はスタンドアロン関数としてエクスポートする必要があります — ページコンポーネントのプロパティとしてgetStaticProps
を追加しても機能しません。
補足: カスタムアプリを作成した場合、リンクされたドキュメントに示されているように、
pageProps
をページコンポーネントに渡していることを確認してください。そうしないと、propsが空になります。
開発環境では毎回リクエスト時に実行
開発環境(next dev
)では、getStaticProps
は毎回のリクエストで呼び出されます。
プレビューモード
プレビューモードを使用することで、静的生成を一時的にバイパスし、ビルド時ではなくリクエスト時にページをレンダリングできます。例えば、ヘッドレスCMSを使用していて、公開前に下書きをプレビューしたい場合などです。