Astroでヘッダーコンポーネントを作成する

サイトのヘッダーやフッターなど、どのページにも表示される共通の部分は、コンポーネントとして切り出すと便利です。コードの重複がなくなり、修正も一箇所で済むため、メンテナンス性が向上します。ここでは、ヘッダーを例にコンポーネント化して再利用できるようにする手順を紹介します。

## ヘッダーコンポーネント作成手順

### 1.コンポーネントファイルを作成する (`src/components/Header.astro`)
まず、コンポーネントファイルを置くためのディレクトリを用意します。通常は `src/` ディレクトリの中に `components/` という名前のディレクトリを作成します。

作成した `src/components/` ディレクトリの中に、`Header.astro` という名前で新しいファイルを作成します。

```
your-project/
└── src/
    ├── components/     <-- このディレクトリを作成
    │   └── Header.astro <-- このファイルを作成
    ├── content/
    ├── layouts/
    ├── pages/
    └── styles/
```

### 2.ヘッダーのHTMLを記述する
作成した `src/components/Header.astro` ファイルを開き、ヘッダーとして表示したいHTML構造を記述します。

ヘッダーのHTMLはすでに作りたいデザインがあればそれをHTML化します。

これからデザインを作る場合は[Tailwindのコンポーネント](https://www.creative-tim.com/twcomponents)やFigmaのデザインテンプレートである[WEB-UIKIT](https://designup.jp/product-web-uikit.html)がおすすめです。

ここでは例として、サイトタイトルと簡単なナビゲーションリンクを持つヘッダーを作成します。

```astro
{/* src/components/Header.astro */}
<header class="bg-blue-600 text-white p-4 shadow-md"> {/* Tailwind CSSでスタイル付けの例 */}
  <div class="container mx-auto flex justify-between items-center">
    <a href="/" class="text-2xl font-bold hover:text-blue-200">My Astro Blog</a>
    <nav>
      <a href="/" class="px-3 hover:text-blue-200">ホーム</a>
      <a href="/tags/" class="px-3 hover:text-blue-200">タグ一覧</a>
      {/* 他に必要なリンクがあれば追加 */}
    </nav>
  </div>
</header>
```
Astroコンポーネントのテンプレート部分は、通常のHTMLのように記述できます。

Tailwind CSSを使っている場合は、このように直接クラスを記述してスタイルを適用できます。

### 3.コンポーネントをレイアウトで使用する

* 作成した `Header` コンポーネントを、サイト全体の共通レイアウトファイル（例: `src/layouts/BaseLayout.astro`）で読み込んで配置します。
* `src/layouts/BaseLayout.astro` ファイルを開きます。
* **フロントマター部分 (`---` 内) で `Header` コンポーネントをインポートします。**

```astro
---
// src/layouts/BaseLayout.astro
import Header from '../components/Header.astro'; // ← Headerコンポーネントをインポート
import Footer from '../components/Footer.astro'; // (例：フッターもコンポーネント化している場合)
import '../styles/global.css';

const { title } = Astro.props;
---
```
* `import Header from '../components/Header.astro';` のように、レイアウトファイルから見た `Header.astro` への **相対パス** で指定します。

* **テンプレート部分で `<Header />` タグを使って配置します。** 通常は `<body>` タグの直下などが適切です。

```astro
---
// --- 上記のフロントマター ---
---
<html lang="ja">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />
  <link rel="icon" href="/favicon.ico" />
  <title>{title}</title>
</head>
<body class="flex flex-col min-h-screen"> {/* Tailwindでフッターを最下部に固定する例 */}
  <Header /> {/* ← ここでヘッダーコンポーネントを呼び出す */}

  <main class="container mx-auto p-4 flex-grow"> {/* ページの主要コンテンツ */}
    <slot /> {/* ← 各ページのコンテンツがここに挿入される */}
  </main>

  {/* <Footer /> フッターコンポーネントを呼び出す例 */}
</body>
</html>
```
これで、この `BaseLayout` を使っているすべてのページに、自動的に `Header` コンポーネントが表示されるようになります。

## Propsを使ってコンポーネントで動的要素を表示する

もしページごとにヘッダーの表示内容（例: タイトル）を変えたい場合は、「Props（プロップス）」という仕組みを使います。

**コンポーネント側 (`Header.astro`) で受け取る:**
```astro
---
// src/components/Header.astro
interface Props {
  siteTitle?: string; // オプショナルなPropsとして定義
}
const { siteTitle = "My Astro Blog" } = Astro.props; // デフォルト値を設定
---
<header class="bg-blue-600 text-white p-4 shadow-md">
  <div class="container mx-auto flex justify-between items-center">
    {/* Propsで受け取ったタイトルを表示 */}
    <a href="/" class="text-2xl font-bold hover:text-blue-200">{siteTitle}</a>
    <nav>
      {/* ... ナビゲーション ... */}
    </nav>
  </div>
</header>
```

**呼び出し側 (`BaseLayout.astro` など) で渡す:**
```astro
<Header siteTitle="特別なページのタイトル" /> {/* Propsを渡す */}
{/* Propsを渡さない場合はデフォルト値が使われる */}
```

### 開発サーバーでの確認

開発サーバーを起動 (`npm run dev` など) して、サイトの各ページにアクセスします。

すべてのページでヘッダーが共通して表示され、リンクなどが正しく機能しているか確認してください。

## まとめ
これでヘッダーのコンポーネント化は完了です！ 同様にフッターやサイドバーなど、他の共通部分もコンポーネント化していくことで、より整理されたコードベースになります。