Open6

getServerSideProps

あおけんあおけん

getServerSidePropsはNext.jsの関数で、
リクエスト時にデータを取得して、
ページの内容をレンダリングするために使用できる。

あおけんあおけん

Example

getServerSidePropsはページコンポーネントからエクスポートして使用することができる。
以下の例では、getServerSidePropsでサードパーティのAPIからデータを取得し、
そのデータをpropsとしてページに渡す方法を示している。

// pages/index.tsx
import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
 
type Repo = {
  name: string
  stargazers_count: number
}
 
export const getServerSideProps = (async () => {
  // Fetch data from external API
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo: Repo = await res.json()
  // Pass data to the page via props
  return { props: { repo } }
}) satisfies GetServerSideProps<{ repo: Repo }>
 
export default function Page({
  repo,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  return (
    <main>
      <p>{repo.stargazers_count}</p>
    </main>
  )
}
あおけんあおけん

When should I use getServerSideProps?

パーソナライズされたユーザデータや、
リクエスト時にしかわからない情報に依存するページをレンダリングする必要がある場合は、getServerSideProps を使うべき。
たとえば、authorization headers や geolocation など。

リクエスト時にデータを取得する必要がない場合や、
データやプリレンダリングされたHTMLをキャッシュしたい場合は、
getStaticPropsを使用することがお勧め。

あおけんあおけん

Behavior

  • サーバー上で実行
  • ページからしかエクスポートできない
  • JSONを返す
  • ユーザがページにアクセスすると、getServerSidePropsはリクエスト時にデータを取得するために使用
    • そのデータはページの初期HTMLをレンダリングするために使用
  • ページ・コンポーネントに渡されたpropsは、最初のHTMLの一部としてクライアントで見れる
    • これはページが正しくハイドレイトされるようにするため
    • propsのクライアントで利用可能であってはならない機密情報を渡さないこと
  • ユーザーが next/link または next/router でページにアクセスすると、Next.jsはサーバーにAPIリクエストを送信し、サーバーはgetServerSidePropsを実行
  • getServerSidePropsはサーバー上で動作する
    • Next.jsのAPIルートを呼び出してデータを取得する必要はない
    • 代わりに、getServerSidePropsの内部からCMSやデータベースなどのサードパーティAPIを直接呼び出すことができる
あおけんあおけん

Error Handling

getServerSideProps内でエラーがスローされた場合、
pages/500.jsファイルが表示される。

開発中はこの500.jsは使用されず、
代わりに開発エラーのオーバーレイが表示。

あおけんあおけん

Edge Cases

Edge Runtime

getServerSidePropsはServerlessランタイムとEdgeランタイムの、
両方で使用でき、両方でpropsを設定できる。

ただし、現在の Edge ランタイムでは、
レスポンス・オブジェクトにアクセスできない。

つまり、たとえば getServerSideProps でクッキーを追加することはできない。
レスポンス・オブジェクトにアクセスするには、
デフォルトのランタイムであるNode.jsランタイムを使用し続ける必要がある。

例えば、configを変更することで、ページごとにランタイムを明示的に設定することができる。

// pages/index.js
export const config = {
  runtime: 'nodejs', // or "edge"
}
 
export const getServerSideProps = async () => {}

Caching with Server-Side Rendering (SSR)

getServerSideProps 内でキャッシュヘッダ (Cache-Control) を使用すると、
動的なレスポンスをキャッシュすることができる。
たとえば、stale-while-revalidate を使用。

// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export async function getServerSideProps({ req, res }) {
  res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  )
 
  return {
    props: {},
  }
}

しかし、キャッシュ制御に手を伸ばす前に、
ISRを使ったgetStaticPropsがあなたのユースケースにより適しているかどうかを確認することをお勧めする。