コンテンツへスキップ

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 パラメータは、次のキーを含むオブジェクトです。

名前説明
params動的ルートを使用するページのルートパラメータを含みます。たとえば、ページ名が[id].jsの場合、params{ id: ... }のようになります。これは後で説明するgetStaticPathsと合わせて使用する必要があります。
preview(draftModeに対して非推奨) ページがプレビューモードの場合はtrue、それ以外の場合はfalseです。
previewData(draftModeに対して非推奨) setPreviewDataによって設定されたプレビューデータ。
draftModedraftModeは、ページがドラフトモードの場合はtrue、それ以外の場合はfalseです。
localeアクティブなロケール(有効になっている場合)を含みます。
localesサポートされているすべてのロケール(有効になっている場合)を含みます。
defaultLocale設定されたデフォルトのロケール(有効になっている場合)を含みます。
revalidateReason関数が呼び出された理由を示します。「build」(ビルド時に実行)、「stale」(再検証期間が経過した、または開発モードで実行)、「on-demand」(オンデマンド再検証を介してトリガー)のいずれかになります。

getStaticProps の戻り値

getStaticProps関数は、propsredirect、または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.0App Routerが、簡素化されたデータ取得機能と共に安定版になりました。
v12.2.0オンデマンドインクリメンタルスタティックリジェネレーションが安定版になりました。
v12.1.0オンデマンドインクリメンタルスタティックリジェネレーションを追加(ベータ版)。
v10.0.0localelocalesdefaultLocalenotFoundオプションを追加。
v10.0.0fallback: 'blocking' 返却オプションを追加。
v9.5.0安定版インクリメンタルスタティックリジェネレーション
v9.3.0getStaticPropsを導入。