Menu

getStaticProps

ページからgetStaticProps(静的サイト生成)という関数をエクスポートすると、Next.jsはビルド時にこのページを事前レンダリングし、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
}

レンダリングの種類に関わらず、すべてのpropsはページコンポーネントに渡され、初期HTMLでクライアント側で表示できることに注意してください。これはページが正しくハイドレートされるようにするためです。クライアント側で利用可能であるべきでない機密情報をpropsに渡さないようにしてください。

getStaticProps APIリファレンスでは、getStaticPropsで使用できるすべてのパラメータとpropsについて説明しています。

getStaticPropsをいつ使用すべきか

以下の場合はgetStaticPropsを使用する必要があります。

  • ページのレンダリングに必要なデータがビルド時にユーザーのリクエストよりも前に利用可能である
  • データがヘッドレスCMSから提供されている
  • ページが事前にレンダリングされている必要がある(SEOのため)で、非常に高速である必要がある。getStaticPropsHTMLJSONファイルの両方を生成し、両方ともCDNでキャッシュできてパフォーマンスが向上する
  • データは公開キャッシュ可能である(ユーザー固有ではない)。この条件は、Proxyを使用してパスを書き直すことで、特定の状況では回避できます。

getStaticPropsはいつ実行されるか

getStaticPropsは常にサーバー上で実行され、クライアント上では実行されません。getStaticProps内に記述されたコードがクライアント側のバンドルから削除されていることをこのツールで検証できます。

  • getStaticPropsは常にnext build中に実行されます
  • getStaticPropsfallback: trueを使用する場合、バックグラウンドで実行されます
  • getStaticPropsfallback: blockingを使用する場合、初期レンダリング前に呼び出されます
  • getStaticPropsrevalidateを使用する場合、バックグラウンドで実行されます
  • getStaticPropsrevalidate()を使用する場合、オンデマンドでバックグラウンドで実行されます

増分静的再生成と組み合わせると、getStaticPropsは古いページの再検証中にバックグラウンドで実行され、新しいページがブラウザに提供されます。

getStaticPropsは静的HTMLを生成するため、受信リクエスト(クエリパラメータやHTTPヘッダーなど)にアクセスできません。ページのリクエストにアクセスする必要がある場合は、getStaticPropsと同様にProxyの使用を検討してください。

CMSからデータを取得するgetStaticPropsの使用

次の例は、CMSからブログ投稿のリストを取得する方法を示しています。

pages/blog.tsx
TypeScript
// postsはビルド時にgetStaticProps()によって入力されます
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}
 
// この関数はビルド時にサーバー側で呼び出されます。
// クライアント側では呼び出されないため、直接データベースを
// クエリすることもできます。
export async function getStaticProps() {
  // 外部APIエンドポイントを呼び出して投稿を取得します。
  // 任意のデータ取得ライブラリを使用できます
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  // { props: { posts } }を返すことで、Blogコンポーネント
  // はビルド時に`posts`をpropとして受け取ります
  return {
    props: {
      posts,
    },
  }
}

getStaticProps APIリファレンスでは、getStaticPropsで使用できるすべてのパラメータとpropsについて説明しています。

サーバー側のコードを直接記述する

getStaticPropsはサーバー側でのみ実行されるため、クライアント側では実行されません。ブラウザ用のJSバンドルにも含まれないため、データベースのクエリをブラウザに送信することなく直接記述できます。

つまり、getStaticPropsからAPIルートを取得する(そのAPIルート自体が外部ソースからデータを取得する)のではなく、getStaticProps内でサーバー側のコードを直接記述できます。

次の例を見てください。APIルートはCMSからいくつかのデータを取得するために使用されます。その後、そのAPIルートはgetStaticPropsから直接呼び出されます。これにより追加呼び出しが発生し、パフォーマンスが低下します。代わりに、CMSからデータを取得するロジックをlib/ディレクトリを使用して共有できます。その後、getStaticPropsで共有できます。

lib/load-posts.js
// 以下の関数は
// getStaticPropsおよびAPIルートと
// `lib/`ディレクトリから共有されます
export async function loadPosts() {
  // 外部APIエンドポイントを呼び出して投稿を取得します
  const res = await fetch('https://.../posts/')
  const data = await res.json()
 
  return data
}
pages/blog.js
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
 
// この関数はサーバー側でのみ実行されます
export async function getStaticProps() {
  // `/api`ルートを取得する代わりに、同じ
  // 関数を`getStaticProps`内で直接呼び出すことができます
  const posts = await loadPosts()
 
  // 返されるPropsはページコンポーネントに渡されます
  return { props: { posts } }
}

または、APIルートを使用してデータを取得していない場合、fetch() APIをgetStaticProps内で直接使用してデータを取得できます。

Next.jsがクライアント側バンドルから何を削除するかを確認するには、next-code-elimination toolを使用できます。

HTMLとJSONの両方を静的に生成する

ページがgetStaticPropsでビルド時に事前レンダリングされると、ページHTMLファイルに加えて、Next.jsはgetStaticPropsの実行結果を保持するJSONファイルを生成します。

このJSONファイルはnext/linkまたはnext/routerを通じたクライアント側ルーティングで使用されます。getStaticPropsを使用して事前レンダリングされたページにナビゲートすると、Next.jsはこのJSONファイル(ビルド時に事前計算)を取得し、ページコンポーネントのpropsとして使用します。つまり、クライアント側のページ遷移はエクスポートされたJSONのみが使用されるため、getStaticPropsを呼び出さません

増分静的生成を使用する場合、getStaticPropsはバックグラウンドで実行され、クライアント側ナビゲーション用のJSONを生成します。これは同じページに対して複数のリクエストが行われる形で表示される場合がありますが、これは意図したもので、エンドユーザーのパフォーマンスに影響を与えません。

getStaticPropsはどこで使用できるか

getStaticPropsページからのみエクスポートできます。ページ以外のファイル、_app_document、または_errorからエクスポートすることはできません

この制限の理由の1つは、Reactがページをレンダリングする前にすべての必要なデータを持つ必要があるためです。

また、getStaticPropsをスタンドアロン関数としてエクスポートする必要があります。ページコンポーネントのプロパティとしてgetStaticPropsを追加しても、動作しません

補足カスタムアプリを作成した場合は、リンクされたドキュメントに示されているように、pagePropsをページコンポーネントに渡していることを確認してください。そうしないと、propsが空になります。

開発時のすべてのリクエストで実行される

開発(next dev)では、getStaticPropsがすべてのリクエストで呼び出されます。

プレビューモード

プレビューモードを使用して、ビルド時の代わりにリクエスト時にページをレンダリングすることで、静的生成を一時的にバイパスできます。たとえば、ヘッドレスCMSを使用していて、公開される前にドラフトをプレビューしたい場合があります。