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
}
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
}
レンダリングタイプに関係なく、すべての
props
はページコンポーネントに渡され、初期 HTML でクライアント側から確認できることに注意してください。これはページが正しくハイドレートされるためです。クライアント側で利用可能にしてはいけない機密情報をprops
に含めないように注意してください。
getStaticProps
API リファレンスでは、getStaticProps
で使用できるすべてのパラメータと props を網羅しています。
getStaticProps を使用すべきケース
以下の場合に getStaticProps
を使用するべきです:
- ページのレンダリングに必要なデータがユーザーのリクエスト前にビルド時に利用可能である場合
- データがヘッドレス CMS から取得される場合
- ページが SEO のためにプリレンダリングされ、非常に高速である必要がある場合 —
getStaticProps
はHTML
とJSON
ファイルを生成し、どちらも CDN でキャッシュ可能でパフォーマンス向上に寄与します - データが公開キャッシュ可能な場合(ユーザー固有でない場合)。特定の状況では、ミドルウェアを使用してパスを書き換えることでこの条件を回避できます
getStaticProps が実行されるタイミング
getStaticProps
は常にサーバー側で実行され、クライアント側では決して実行されません。このツールを使用して、getStaticProps
内のコードがクライアント側のバンドルから削除されていることを確認できます。
getStaticProps
は常にnext build
時に実行されますfallback: true
使用時にはバックグラウンドで実行されますfallback: blocking
使用時には初期レンダリング前に呼び出されますrevalidate
使用時にはバックグラウンドで実行されますrevalidate()
使用時にはオンデマンドでバックグラウンドで実行されます
インクリメンタル静的再生成と組み合わせた場合、getStaticProps
は古いページが再検証されている間バックグラウンドで実行され、新しいページがブラウザに提供されます。
getStaticProps
は静的 HTML を生成するため、受信リクエスト(クエリパラメータや HTTP ヘッダーなど)にアクセスできません。ページのリクエストにアクセスする必要がある場合は、getStaticProps
に加えてミドルウェアの使用を検討してください。
CMS からデータを取得する getStaticProps の使用例
以下の例は、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` を prop として受け取ります
return {
props: {
posts,
},
}
}
// 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` を prop として受け取ります
return {
props: {
posts,
},
}
}
getStaticProps
API リファレンスでは、getStaticProps
で使用できるすべてのパラメータと props を網羅しています。
サーバーサイドコードを直接記述
getStaticProps
はサーバー側でのみ実行されるため、クライアント側では決して実行されません。ブラウザ用の JS バンドルにも含まれないため、データベースクエリを直接記述してもブラウザに送信されることはありません。
これは、getStaticProps
から(外部ソースからデータを取得する)API ルートをフェッチする代わりに、getStaticProps
内に直接サーバーサイドコードを記述できることを意味します。
次の例を考えてみましょう。API ルートは CMS からデータを取得するために使用されます。その API ルートは getStaticProps
から直接呼び出されます。これにより追加の呼び出しが発生し、パフォーマンスが低下します。代わりに、CMS からデータを取得するロジックは lib/
ディレクトリを使用して共有できます。その後、getStaticProps
と共有できます。
// 以下の関数は `lib/` ディレクトリから
// getStaticProps と API ルートで共有されます
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 ツールを使用できます。
HTML と JSON の両方を静的に生成
getStaticProps
を使用したページがビルド時にプリレンダリングされるとき、Next.js はページ HTML ファイルに加えて、getStaticProps
の実行結果を含む JSON ファイルも生成します。
この 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 を使用していて、公開前に下書きをプレビューしたい場合などに便利です。