個人的備忘録：src/app/page.tsxを読み解きながら、Tailwind + Next.jsで組むトップページ構成とUIレイアウトを整理してみた

## はじめに
Next.js プロジェクトの中で、`src/app/page.tsx` はトップページ（ルートページ）を構成する重要なコンポーネントです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、以下のコードを例に、ページの構成と機能について解説します。

---

## コード全体の構造と機能

```tsx
"use client";

import { useEffect, useState } from "react";
import Image from "next/image";

export default function Home() {
  const [message, setMessage] = useState("Loading...");

  useEffect(() => {
    fetch("http://localhost:8000/")
      .then((res) => res.json())
      .then((data) => setMessage(data.message))
      .catch(() => setMessage("Error fetching message from FastAPI."));
  }, []);

  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
        <Image
          className="dark:invert"
          src="/next.svg"
          alt="Next.js logo"
          width={180}
          height={38}
          priority
        />

        <div className="text-lg text-center sm:text-left font-bold text-blue-600">
          {message}
        </div>

        <ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
          <li className="mb-2 tracking-[-.01em]">
            You are now connected to FastAPI backend!
          </li>
          <li className="tracking-[-.01em]">
            Edit <code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-semibold">src/app/page.tsx</code> to customize.
          </li>
        </ol>

        <div className="flex gap-4 items-center flex-col sm:flex-row">
          <a
            className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
            href="https://vercel.com/new"
            target="_blank"
            rel="noopener noreferrer"
          >
            <Image
              className="dark:invert"
              src="/vercel.svg"
              alt="Vercel logomark"
              width={20}
              height={20}
            />
            Deploy now
          </a>
          <a
            className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
            href="https://nextjs.org/docs"
            target="_blank"
            rel="noopener noreferrer"
          >
            Read our docs
          </a>
        </div>
      </main>

      <footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://nextjs.org/learn"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src="/file.svg"
            alt="File icon"
            width={16}
            height={16}
          />
          Learn
        </a>
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://vercel.com/templates?framework=next.js"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src="/window.svg"
            alt="Window icon"
            width={16}
            height={16}
          />
          Examples
        </a>
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://nextjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src="/globe.svg"
            alt="Globe icon"
            width={16}
            height={16}
          />
          Go to nextjs.org →
        </a>
      </footer>
    </div>
  );
}
```

---

## 解説ポイント

### 「use client」
Next.js の App Router では、デフォルトでサーバーコンポーネントになりますが、クライアント機能（`useEffect` や `useState` など）を使う場合に必要な宣言です。

### `useState` と `useEffect`
- `useState`：状態変数 `message` を管理します。
- `useEffect`：コンポーネントがマウントされたときに一度だけ FastAPI にアクセスし、データを取得します。

### レイアウト
Tailwind CSS によって、以下のようなレスポンシブかつ整ったレイアウトを実現しています：
- ロゴ表示（Next.js）
- FastAPI からのメッセージ
- 操作ガイド
- デプロイ & ドキュメントリンク
- フッターに学習リソースのリンク

---

## まとめ
この `page.tsx` は、Next.js + FastAPI 構成での典型的なフロントエンドの入り口です。

:::note warn
***シンプルな構成ながら、バックエンドとの通信、状態管理、スタイリングなど、実践的な学習要素が詰まっています。***
:::

自分のAPIを組み込む際にもこの構成をベースに調整できます...！