コンテンツにスキップ

getStaticProps

ページから getStaticProps (Static Site Generation) という名前の関数をエクスポートすると、Next.js は 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
}

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

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

getStaticProps はいつ使用すべきか?

getStaticProps を使用すべきなのは、

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

getStaticProps はいつ実行されるか

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

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

インクリメンタル静的再生成 (Incremental Static Regeneration) と組み合わせると、getStaticProps は、古いページが再生成されている間にバックグラウンドで実行され、新しいページがブラウザに提供されます。

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

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

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

pages/blog.tsx
// posts will be populated at build time by getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</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() {
  // Call an external API endpoint to get posts.
  // You can use any data fetching library
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  }
}

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

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

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

これは、getStaticProps から APIルート を取得する代わりに(それは外部ソースからデータを取得する)、getStaticProps 内にサーバーサイドコードを直接記述できることを意味します。

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

lib/load-posts.js
// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
  // Call an external API endpoint to get posts
  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'
 
// This function runs only on the server side
export async function getStaticProps() {
  // Instead of fetching your `/api` route you can call the same
  // function directly in `getStaticProps`
  const posts = await loadPosts()
 
  // Props returned will be passed to the page component
  return { props: { posts } }
}

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

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

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

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

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

インクリメンタル静的生成を使用する場合、getStaticProps は、クライアントサイドナビゲーションに必要なJSONを生成するためにバックグラウンドで実行されます。同じページに対して複数のリクエストが発生しているように見えるかもしれませんが、これは意図されたものであり、エンドユーザーのパフォーマンスには影響しません。

getStaticProps はどこで使用できますか?

getStaticPropsページ からのみエクスポートできます。非ページファイル、_app_document_error からはエクスポートできません。

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

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

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

開発時にはリクエストごとに実行される

開発時(next dev)には、getStaticProps はリクエストごとに呼び出されます。

Preview Mode

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