コンテンツへスキップ

getStaticProps

getStaticProps という関数をエクスポートすると、その関数から返されたpropsを使用してビルド時にページがプリレンダリングされます。

pages/index.tsx
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パラメーター

context パラメーターは、以下のキーを含むオブジェクトです。

名前説明
paramsダイナミックルートを使用するページのルートパラメーターが含まれます。例えば、ページ名が [id].js の場合、params{ id: ... } のようになります。これは getStaticPaths と一緒に使用する必要があります。これについては後で説明します。
previewdraftMode で非推奨)ページがプレビューモードの場合、previewtrue になり、それ以外の場合は false になります。
previewDatadraftMode で非推奨)setPreviewData で設定されたプレビューデータです。
draftModeページがドラフトモードの場合、draftModetrue になり、それ以外の場合は false になります。
localeアクティブなロケールが含まれます(有効な場合)。
localesサポートされているすべてのロケールが含まれます(有効な場合)。
defaultLocale設定されたデフォルトロケールが含まれます(有効な場合)。
revalidateReason関数が呼び出された理由を提供します。以下のいずれかです:「build」(ビルド時に実行)、「stale」(再検証期間が期限切れになった、または開発モードで実行中)、「on-demand」(オンデマンド再検証によってトリガーされた)

getStaticPropsの戻り値

getStaticProps 関数は、propsredirect、または notFound のいずれかを含むオブジェクトを返し、その後に**オプションで** revalidate プロパティが続きます。

props

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
  }
}

Incremental Static Regenerationについて詳しくはこちら。

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 }, // 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 を使用することはできません。__dirname が返すパスはPages Routerとは異なるためです。

代わりに、Next.jsが実行されているディレクトリを返す process.cwd() を使用できます。

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.0App Routerが、簡素化されたデータフェッチで安定版になりました。
v12.2.0オンデマンドIncremental Static Regenerationが安定版になりました。
v12.1.0オンデマンドIncremental Static Regenerationが追加されました(ベータ版)。
v10.0.0localelocalesdefaultLocale、および notFound オプションが追加されました。
v10.0.0fallback: 'blocking' 戻り値オプションが追加されました。
v9.5.0安定版Incremental Static Regeneration
v9.3.0getStaticProps が導入されました。