Dev Study
← 解説「Server Components — サーバーでHTMLを作る」に戻る

サンプルコードで身につける: Server Components — サーバーでHTMLを作る

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1最小の Server Component

何も書かなければ Server Component になる、という既定の動作を確かめる最小の例です。console.log がブラウザではなく npm run dev のターミナルに出ることが、サーバーで実行されている何よりの証拠になります。

// app/page.tsx — 特別な記述ゼロで Server Component
export default function HomePage() {
  console.log("これはターミナルに出る(ブラウザには出ない)");
  return <h1>ようこそ</h1>;
}

// ブラウザに届くのは実行後の HTML だけ。
// この関数のコードそのものはブラウザに送られない。

2サーバーの時刻でHTMLを作る

コンポーネントの中の処理がサーバー側で実行されてから HTML になる、という順序を時刻で確かめる例です。「いつ・どこで実行されたか」を画面に出してみるのは、Server Component の動きを理解する一番手軽な実験です。

// app/page.tsx
export default function HomePage() {
  // この計算はサーバーで行われ、結果だけが HTML に埋め込まれる
  const builtAt = new Date().toLocaleString("ja-JP");
  return (
    <main>
      <h1>ようこそ</h1>
      <p>この HTML はサーバーで {builtAt} に組み立てられました。</p>
    </main>
  );
}

3APIキーを隠したまま使う

Server Component の大きな利点である「秘密情報をブラウザに見せずに使える」を示す例です。環境変数の API キーはサーバー上でだけ読まれ、ブラウザに届く HTML には結果しか含まれないため、開発者ツールで覗いても漏れません。

// app/weather/page.tsx — API キーはサーバーから出ない
export default function WeatherPage() {
  // 環境変数はサーバーでだけ読める。ブラウザには送られない
  const apiKey = process.env.WEATHER_API_KEY;

  // 本来はこのキーを使って天気 API を呼ぶ(呼び方は後のレッスンで)
  const hasKey = apiKey !== undefined;

  return (
    <main>
      <h1>天気予報</h1>
      <p>APIキーの設定: {hasKey ? "済み" : "未設定"}</p>
      {/* HTML に含まれるのはこの結果だけ。キー本体は含まれない */}
    </main>
  );
}

4「データ→HTML」の変換を再現する

Server Component の仕事を「データを受け取って HTML 文字列を返す変換」として捉え直し、プレーンな TypeScript で実行する例です。ブラウザに届くのが完成品の HTML だけで、変換コード自体は送られない、という分担が明確になります。

TypeScript

5サーバーのファイルを直接読むページ

Node.js の fs モジュールでサーバー上のファイルを直接読み込む、Server Component ならではの実務例です。ブラウザで動く従来の React では不可能だったことで、お知らせやドキュメントを JSON やマークダウンのファイルで管理する構成が手軽に作れます。

// app/news/page.tsx — サーバー上の JSON ファイルを直接読む
import { readFileSync } from "node:fs";

type NewsItem = { date: string; text: string };

export default function NewsPage() {
  // fs はサーバーでしか動かない。Server Component だから書ける
  const json = readFileSync("data/news.json", "utf-8");
  const items: NewsItem[] = JSON.parse(json);

  return (
    <ul>
      {items.map((item) => (
        <li key={item.date}>
          {item.date}: {item.text}
        </li>
      ))}
    </ul>
  );
}