本文へ移動
verified onnext@16.3.3react@19
最終検証日 2026-08-27
Next.js道場

Server Component とは何か

Server Component は、サーバー側だけで実行され、その JavaScript がブラウザに送られない React コンポーネントです。

#何が違うのか

これまでの React では、書いたコンポーネントは最終的にブラウザで動いていました。サーバーが HTML を先に作る構成(SSR)でも、同じコードがブラウザにも送られて、そこでもう一度動きます。

Server Component は違います。サーバーで一度動いて、結果だけを送ります。 そのコンポーネントの JavaScript はブラウザに届きません。

これまで          コード ──▶ サーバーで実行 ──▶ HTML
                  コード ──────────────────▶ ブラウザでも実行

Server Component  コード ──▶ サーバーで実行 ──▶ 結果だけ
                  (コードはブラウザに届かない)

#App Router ではこれが既定

app/ の下に書いたコンポーネントは、何も書かなければ Server Component です。Client Component にしたいときだけ、明示的に宣言します。

この既定が逆だと思っていると、ほぼすべての判断がずれます。まずここを押さえてください。

#できること

DB に直接アクセスできる

API を経由する必要がありません。

// app/products/page.tsx
export default async function Page() {
  const items = await db.item.findMany()
  return <List items={items} />
}

自分自身の API ルートを fetch で呼ぶ書き方をよく見かけますが、Server Component では遠回りです。サーバーの中にいるので、直接読めます。

秘密を扱える

API キーや DB の接続情報を、そのまま使えます。このコードはブラウザに届かないからです。

ただし渡した props はブラウザに届きます。ここが分かれ目です。

// これは安全(key はサーバーの中だけ)
const data = await fetch(url, { headers: { Authorization: key } })

// これは漏れる(key が props としてブラウザへ届く)
return <Panel apiKey={key} />

async にできる

コンポーネントそのものを async にして await できます。データ取得のために useEffect と状態を組む必要がありません。

#できないこと

できないこと理由
useState useReducer状態はブラウザ側のもの
useEffect描画後の副作用はブラウザ側のもの
onClick などのイベント押すのはブラウザ
window documentサーバーに存在しない
localStorage同上

これらが必要になった時点で、その部分だけを Client Component に切り出します。

#何がブラウザに届くのか

Server Component が返した内容は、HTML と RSC ペイロードという形で送られます。コードではなく、描画の結果です。

つまり、

  • 表示している値は届く(当然、画面に出るので)
  • 表示していない値も、props として渡していれば届く
  • コンポーネントの中で使っただけの変数は届かない

「画面に出ていないから安全」ではありません。境界を越えた props はすべて届きます。

#使い分けの目安

まず Server Component で書き始めて、ブラウザが必要になったところだけを切り出すのが基本です。

app/products/[id]/page.tsx      Server(DB から商品を取得)
├─ ProductInfo                   Server(表示するだけ)
├─ ReviewList                    Server(表示するだけ)
└─ AddToCartButton               Client(ここだけ)

逆に「とりあえず全部 Client にして、必要なら Server に戻す」という進め方は、送る JavaScript が増えるうえ、DB へ直接アクセスできる利点も失います。

#よくある誤解

SSR と同じもの?

違います。SSR は「同じコードをサーバーでも動かす」仕組みで、コードはブラウザにも送られます。Server Component はそもそもブラウザに送らない仕組みです。両方を同時に使うこともできます。

静的なページ専用?

違います。リクエストごとに実行することもできます。何をいつ実行するかは、Cookie や検索パラメータを読むかどうかなどで決まります。

遅くなる?

送る JavaScript が減るぶん、ブラウザ側の負担は軽くなります。ただしサーバー側の処理が遅ければページ全体が遅くなるので、そこは Suspense で分割します。

理解できたか試す

では、このコードはどうなりますか。

このページには use client がありません。どうなりますか。

この問題を解くこのテーマの問題 3