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
}
getStaticProps
で使用するトップレベルスコープにモジュールをインポートできます。使用されたインポートは**クライアント側にはバンドルされません**。つまり、データベースからのデータのフェッチを含む、**getStaticProps
にサーバーサイドコードを直接記述**できます。
コンテキストパラメータ
context
パラメータは、次のキーを含むオブジェクトです。
名前 | 説明 |
---|---|
params | 動的ルートを使用するページのルートパラメータを含みます。たとえば、ページ名が[id].js の場合、params は{ id: ... } のようになります。これは後で説明するgetStaticPaths と合わせて使用する必要があります。 |
preview | (draftMode に対して非推奨) ページがプレビューモードの場合はtrue 、それ以外の場合はfalse です。 |
previewData | (draftMode に対して非推奨) setPreviewData によって設定されたプレビューデータ。 |
draftMode | draftMode は、ページがドラフトモードの場合はtrue 、それ以外の場合はfalse です。 |
locale | アクティブなロケール(有効になっている場合)を含みます。 |
locales | サポートされているすべてのロケール(有効になっている場合)を含みます。 |
defaultLocale | 設定されたデフォルトのロケール(有効になっている場合)を含みます。 |
revalidateReason | 関数が呼び出された理由を示します。「build」(ビルド時に実行)、「stale」(再検証期間が経過した、または開発モードで実行)、「on-demand」(オンデマンド再検証を介してトリガー)のいずれかになります。 |
getStaticProps の戻り値
getStaticProps
関数は、props
、redirect
、またはnotFound
を含むオブジェクトを返し、その後、**オプション**でrevalidate
プロパティを返す必要があります。
props
props
オブジェクトはキーバリューペアで、各値はページコンポーネントによって受信されます。これはシリアライズ可能なオブジェクトであるため、渡されたプロパティはJSON.stringify
でシリアライズできます。
export async function getStaticProps(context) {
return {
props: { message: `Next.js is awesome` }, // will be passed to the page component as props
}
}
revalidate
revalidate
プロパティは、ページの再生成が行われるまでの秒数です(デフォルトはfalse
、つまり再検証なしです)。
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
インクリメンタルスタティックリジェネレーションについて詳しく学ぶ。
ISRを利用したページのキャッシュ状態は、x-nextjs-cache
レスポンスヘッダーの値を読み取ることで確認できます。考えられる値は以下のとおりです。
MISS
- パスはキャッシュにありません(初回アクセス時のみ発生します)。STALE
- パスはキャッシュにありますが、revalidate
時間が経過しているため、バックグラウンドで更新されます。HIT
- パスはキャッシュにあり、revalidate
時間が経過していません。
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 }, // will be passed to the page component as props
}
}
重要な点:
fallback: false
モードでは、getStaticPaths
から返されたパスのみが事前にレンダリングされるため、notFound
は必要ありません。
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 }, // will be passed to the page component as props
}
}
リダイレクトがビルド時にわかっている場合は、next.config.js
に追加する必要があります。
ファイルの読み取り: process.cwd()
を使用する
ファイルは、getStaticProps
でファイルシステムから直接読み取ることができます。
そのためには、ファイルへのフルパスを取得する必要があります。
Next.jsはコードを別のディレクトリにコンパイルするため、__dirname
はパスとして使用できません。これは、Pages Routerとは異なるパスを返すためです。
代わりに、process.cwd()
を使用できます。これは、Next.jsが実行されているディレクトリを返します。
import { promises as fs } from 'fs'
import path from 'path'
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>
<h3>{post.filename}</h3>
<p>{post.content}</p>
</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
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')
// Generally you would parse/transform the contents
// For example you can transform markdown to HTML here
return {
filename,
content: fileContents,
}
})
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
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 | 安定版インクリメンタルスタティックリジェネレーション |
v9.3.0 | getStaticProps を導入。 |
役に立ちましたか?