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 パラメータ

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 関数は propsredirect、または 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 はコードを別のディレクトリにコンパイルするため、__dirname を使用することはできません。返されるパスは Pages Router とは異なります。

代わりに、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.0App Router が安定版となり、データフェッチングが簡素化されました
v12.2.0オンデマンド増分静的再生成 が安定版になりました。
v12.1.0オンデマンド増分静的再生成 が追加されました(ベータ)。
v10.0.0localelocalesdefaultLocalenotFound オプションが追加されました。
v10.0.0fallback: 'blocking' 戻り値オプションが追加されました。
v9.5.0安定版 増分静的再生成
v9.3.0getStaticProps が導入されました。

On this page