getStaticProps
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
}
getStaticProps
で使用するモジュールはトップレベルスコープでインポートできます。インポートされたモジュールはクライアントサイドのバンドルに含まれません。つまり、getStaticProps
内で直接サーバーサイドのコードを記述でき、データベースからのデータ取得も含まれます。
context パラメータ
context
パラメータは以下のキーを含むオブジェクトです:
名前 | 説明 |
---|---|
params | ダイナミックルート を使用するページのルートパラメータを含みます。例えば、ページ名が [id].js の場合、params は { id: ... } のようになります。これは後で説明する getStaticPaths と一緒に使用する必要があります。 |
preview | (非推奨、draftMode を使用) プレビューモード の場合 true 、それ以外は false 。 |
previewData | (非推奨、draftMode を使用) setPreviewData で設定された プレビュー データ。 |
draftMode | ドラフトモード の場合 true 、それ以外は false 。 |
locale | アクティブなロケールを含みます(有効な場合)。 |
locales | サポートされているすべてのロケールを含みます(有効な場合)。 |
defaultLocale | 設定されたデフォルトロケールを含みます(有効な場合)。 |
revalidateReason | 関数が呼び出された理由を提供します。以下のいずれかになります: "build"(ビルド時に実行)、"stale"(再検証期間が切れた、または開発モードで実行中)、"on-demand"(オンデマンド再検証によってトリガー) |
getStaticProps の戻り値
getStaticProps
関数は props
、redirect
、または notFound
のいずれかを含むオブジェクトを返す必要があり、オプションで revalidate
プロパティを含めることができます。
props
props
オブジェクトはキーと値のペアで、各値はページコンポーネントに渡されます。シリアライズ可能なオブジェクトである必要があり、渡されるすべての props は JSON.stringify
でシリアライズ可能でなければなりません。
export async function getStaticProps(context) {
return {
props: { message: `Next.js is awesome` }, // ページコンポーネントに props として渡されます
}
}
revalidate
revalidate
プロパティは、ページの再生成が可能になるまでの秒数です(デフォルトは false
で再検証なし)。
// この関数はビルド時にサーバーサイドで呼び出されます。
// 再検証が有効で新しいリクエストがある場合、
// サーバーレス関数で再度呼び出される可能性があります
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js はページの再生成を試みます:
// - リクエストがあったとき
// - 最大10秒に1回
revalidate: 10, // 秒単位
}
}
増分静的再生成 (ISR) について詳しく学びましょう。
ISR を利用したページのキャッシュステータスは、x-nextjs-cache
レスポンスヘッダーの値を読むことで確認できます。可能な値は以下の通りです:
MISS
- パスがキャッシュにない(最初の訪問時に最大1回発生)STALE
- パスはキャッシュにあるが再検証時間を超えたため、バックグラウンドで更新されるHIT
- パスはキャッシュにあり、再検証時間を超えていない
notFound
notFound
ブール値は、ページが 404
ステータスと 404 ページ を返すことを許可します。notFound: true
の場合、以前に正常に生成されたページがあっても 404
を返します。これは、作者によって削除されたユーザー生成コンテンツなどのユースケースをサポートするためのものです。notFound
はここで説明した revalidate
と同じ動作に従います。
export async function getStaticProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // ページコンポーネントに props として渡されます
}
}
補足:
fallback: false
モードではnotFound
は必要ありません。getStaticPaths
から返されたパスのみが事前レンダリングされるためです。
redirect
redirect
オブジェクトは、内部または外部リソースへのリダイレクトを許可します。{ destination: string, permanent: boolean }
の形式に一致する必要があります。
まれなケースでは、古い HTTP
クライアントが適切にリダイレクトするためにカスタムステータスコードを割り当てる必要がある場合があります。このような場合、permanent
プロパティの代わりに statusCode
プロパティを使用できますが、両方を使用することはできません。また、next.config.js
のリダイレクトと同様に basePath: false
を設定できます。
export async function getStaticProps(context) {
const res = await fetch(`https://...`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
// statusCode: 301
},
}
}
return {
props: { data }, // ページコンポーネントに props として渡されます
}
}
リダイレクトがビルド時にわかっている場合は、next.config.js
に追加するべきです。
ファイルの読み込み: process.cwd()
の使用
getStaticProps
でファイルシステムから直接ファイルを読み取ることができます。
そのためには、ファイルへの完全なパスを取得する必要があります。
Next.js はコードを別のディレクトリにコンパイルするため、Pages Router では __dirname
を使用できません。返されるパスが異なるためです。
代わりに、Next.js が実行されているディレクトリを提供する process.cwd()
を使用できます。
import { promises as fs } from 'fs'
import path from 'path'
// posts は getStaticProps() によってビルド時に生成されます
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>
<h3>{post.filename}</h3>
<p>{post.content}</p>
</li>
))}
</ul>
)
}
// この関数はビルド時にサーバーサイドで呼び出されます。
// クライアントサイドでは呼び出されないので、
// 直接データベースクエリを実行することもできます。
export async function getStaticProps() {
const postsDirectory = path.join(process.cwd(), 'posts')
const filenames = await fs.readdir(postsDirectory)
const posts = filenames.map(async (filename) => {
const filePath = path.join(postsDirectory, filename)
const fileContents = await fs.readFile(filePath, 'utf8')
// 一般的にはコンテンツを解析/変換します
// 例えばマークダウンをHTMLに変換できます
return {
filename,
content: fileContents,
}
})
// { props: { posts } } を返すことで、Blog コンポーネントは
// ビルド時に `posts` を props として受け取ります
return {
props: {
posts: await Promise.all(posts),
},
}
}
export default Blog
バージョン履歴
バージョン | 変更点 |
---|---|
v13.4.0 | App Router が安定版になり、データ取得が簡素化されました |
v12.2.0 | オンデマンド増分静的再生成 が安定版になりました |
v12.1.0 | オンデマンド増分静的再生成 が追加されました(ベータ) |
v10.0.0 | locale 、locales 、defaultLocale 、notFound オプションが追加されました |
v10.0.0 | fallback: 'blocking' 戻り値オプションが追加されました |
v9.5.0 | 安定版 増分静的再生成 (ISR) |
v9.3.0 | getStaticProps が導入されました |