Sponsor
ChatHubChatHub Use GPT-4, Gemini, Claude 3.5 and more chatbots side-by-side
ここをクリック
Menu

getStaticProps

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

pages/index.tsx
TypeScript
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と一緒に使用する必要があります。
previewdraftModeは非推奨)previewは、ページがプレビューモードの場合はtrue、そうでない場合はfalseです。
previewDatadraftModeは非推奨)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は素晴らしい` }, // ページコンポーネントに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を活用するページのキャッシュステータスは、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モードでは、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 }, // ページコンポーネントに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 は 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` をプロップとして受け取ります
  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 が導入されました。