PR

【Next.jsブログ構築】ヘッダーとフッターを実装して全ページ共通レイアウトを作る方法

Next.js のブログにヘッダーとフッターを実装して全ページ共通レイアウトを作る手順を解説するイラスト。女性がノートパソコンで作業し、画面上にサイト名とナビゲーションが表示されたブログの外枠デザインが完成していく様子を表現したアイキャッチ画像 VPS・RentalServer
この記事は約14分で読めます。
記事内に広告が含まれています。
スポンサーリンク

これまでの Next.js ブログサイト構築シリーズをまとめたページは以下の通りです。

前回の第7回では、 Next.js の「動的ルーティング」機能を使い、
トップページの新着記事一覧から個別記事のページへリンクを繋ぎ、
本文を表示する仕組みを構築しました。

記事の一覧表示と個別表示ができるようになりましたが、
どのページを開いても、上部にサイト名はなく、下部にもコピーライトがない、
いわゆる「外枠のない素っ気ない画面」のままです。

この記事では、 Next.js の layout.tsx を使い、
全ページに共通で表示されるヘッダーとフッターをコンポーネントとして実装する手順を解説します。

この記事を読むと、以下のことができるようになります。

  • components フォルダにヘッダーとフッターをコンポーネントとして作成する
  • layout.tsx に組み込んで、全ページに一括で適用する
  • 1ファイルの変更だけで全ページのデザインを管理できる構造を作る

作業の前に:コンポーネントとフォルダ構成を理解する

コンポーネントという考え方

実際の作業に入る前に、今回の核となる「コンポーネント」という考え方を整理しておきます。

Next.js( React )では、画面の部品をコンポーネントという単位で作ります。

レゴブロックをイメージすると分かりやすいと思います。「ヘッダー」というブロックと「フッター」というブロックをそれぞれ独立したファイルとして作っておき、あとから組み合わせる、という作り方です。

部品を独立したファイルに分けておくメリットは以下の通りです。

  • サイト名を変えたいとき、 Header.tsx だけを修正すれば全ページに反映される
  • 同じ部品を複数のページで使い回せる
  • コードが長くなりすぎず、管理しやすくなる

WordPress のウィジェットやテーマ設定に近いものと理解すると良いと思います。

今回の作業で完成するフォルダ構成

今回の作業が完了すると、フォルダ構成は以下のようになります。

example-blog/
├── app/
│   ├── layout.tsx        ← 全ページ共通の外枠(今回編集)
│   ├── page.tsx          ← トップページ(今回一部修正)
│   ├── globals.css
│   └── posts/
│       └── [id]/
│           └── page.tsx  ← 個別記事ページ(今回一部修正)
├── components/           ← 今回新しく作成するフォルダ
│   ├── Header.tsx        ← ヘッダー部品(今回新規作成)
│   └── Footer.tsx        ← フッター部品(今回新規作成)
├── lib/
│   └── posts.ts
└── posts/
    ├── test-1.md
    └── test-2.md

新しく登場するのは components フォルダとその中の2つのファイルです。
それ以外のファイルは、今回の作業で一部修正します。

layout.tsx にヘッダー・フッターを実装する手順

Step 1:コンポーネント用フォルダの作成

ヘッダーとフッターのファイルを保管するための専用フォルダを作成します。
Cursor のターミナルで以下のコマンドを実行してください。

mkdir ~/example-blog/components

mkdir は「 Make Directory 」の略で、新しいフォルダを作成するコマンドです。

Step 2:ヘッダーコンポーネントの作成

続いて、ヘッダーの部品ファイルを作成します。

nano ~/example-blog/components/Header.tsx

黒い画面( nano エディタ)が開いたら、以下のコードをすべて貼り付けます。
貼り付けたら Ctrl + OEnter で保存し、 Ctrl + X でエディタを終了します。

import Link from 'next/link';

export default function Header() {
  return (
    <header className="bg-gray-900 border-b border-gray-700">
      <div className="max-w-3xl mx-auto px-8 py-4 flex items-center justify-between">
        {/* サイト名:クリックするとトップページへ戻る */}
        <Link href="/" className="text-white text-xl font-bold hover:text-gray-300 transition-colors">
          あなたのブログ名
        </Link>

        {/* ナビゲーションメニュー */}
        <nav>
          <ul className="flex gap-6">
            <li>
              <Link href="/" className="text-gray-400 hover:text-white transition-colors text-sm">
                ホーム
              </Link>
            </li>
          </ul>
        </nav>
      </div>
    </header>
  );
}

あなたのブログ名 の部分は、ご自身のブログ名に書き換えてください。

コードのポイント解説

1行目の import Link from 'next/link'; で、 Next.js 専用のリンク部品を読み込んでいます。通常の HTML の <a> タグでも同じようにリンクを作れますが、 Next.js では <Link> を使うことで、ページ全体を読み込み直さずに一瞬で画面が切り替わります。

3行目の export default function Header() の部分が、コンポーネントの定義です。export default をつけることで、他のファイルから import Header from '../components/Header' のように読み込めるようになります。

デザインの設定( className の部分)は、 Tailwind CSS のクラス名を空白区切りで並べて指定します。特にポイントになる部分は以下の通りです。

  • flex items-center justify-between :サイト名とナビゲーションを左右の端に配置する
  • hover:text-gray-300 :マウスが乗ったときに文字色を変えるホバーエフェクト(hover: プレフィックスをつけるのがルール)
  • transition-colors :色の変化をなめらかにアニメーションさせる

ナビゲーションメニューの <li> ブロックを追加することで、後から「カテゴリー」などのリンクを増やせます。

Step 3:フッターコンポーネントの作成

次に、フッターの部品ファイルを作成します。

nano ~/example-blog/components/Footer.tsx

黒い画面が開いたら、以下のコードをすべて貼り付けて保存します( Ctrl + OEnterCtrl + X )。

export default function Footer() {
  return (
    <footer className="bg-gray-900 border-t border-gray-700 mt-16">
      <div className="max-w-3xl mx-auto px-8 py-6 text-center">
        <p className="text-gray-500 text-sm">
          © {new Date().getFullYear()} あなたのブログ名
        </p>
      </div>
    </footer>
  );
}

あなたのブログ名 の部分は、 Header.tsx に入力したものと同じブログ名に書き換えてください。

コードのポイント解説

コピーライト表示の {new Date().getFullYear()} は JavaScript のコードです。実行した時点の西暦を自動で取得します。「2026」と直接書かずに済むため、年が変わっても自動で更新されます。

{} で囲んだ部分が JavaScript のコードとして実行される、 JSX という記法です。 Next.js のコードでは、 HTML に似た構造の中に JavaScript を混ぜて書けます。

Step 4:layout.tsx にヘッダーとフッターを組み込む

今回の作業で最も重要なファイルが app/layout.tsx です。

このファイルは、 全ページ共通の外枠 を定義する Next.js の特別なファイルです。ここにヘッダーとフッターを組み込むことで、すべてのページに自動で適用されます。

nano ~/example-blog/app/layout.tsx

ファイルを開いたら、既存の中身をすべて削除します。 nano では Ctrl + K を繰り返すと1行ずつ削除できます。全行削除したら、以下のコードをまるごと貼り付けて保存します。

import type { Metadata } from "next";
import "./globals.css";
import Header from "../components/Header";
import Footer from "../components/Footer";

export const metadata: Metadata = {
  title: "あなたのブログ名",
  description: "ブログの説明文をここに入力してください",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja" suppressHydrationWarning>
      <body className="bg-gray-950 text-white min-h-screen flex flex-col">
        {/* ヘッダー:全ページの上部に表示 */}
        <Header />

        {/* children:各ページの本文がここに入る */}
        <main className="flex-grow">
          {children}
        </main>

        {/* フッター:全ページの下部に表示 */}
        <Footer />
      </body>
    </html>
  );
}

titledescription の2か所を、ご自身のブログに合わせて書き換えてください。

  • title :ブラウザのタブに表示されるブログ名( Header.tsx に入力したものと同じにする)
  • description :検索エンジンの検索結果に表示されるブログの説明文

コードのポイント解説

このコードの核心部分は {children} です。

children とは、「各ページの本文を受け取るための受け皿」です。トップページ( page.tsx )や個別記事ページの中身が、この {children} の位置に自動的に差し込まれます。

children の型として指定している React.ReactNode は、「 React が画面に表示できるものなら何でも受け取る」という意味です。文字列・画像・他のコンポーネントなど、どんな中身が来ても対応できる、最も汎用的な型指定です。

3つのファイルの関係を図で整理すると、以下のようになります。

layout.tsx(外枠)
├── Header.tsx(上部)
├── {children}( page.tsx の中身がここに差し込まれる)
└── Footer.tsx(下部)

layout.tsx を1か所変更するだけで、全ページのデザインが一括で変わるのが、この構造の最大のメリットです。

min-h-screen flex flex-colflex-grow の組み合わせは、コンテンツが少ない短いページでもフッターが常に画面の一番下に来るようにするための設定です。

layout.tsx という1つのファイルで全ページの見た目を管理できるのは、合理的でとても良いです。
今後デザインを変えるときも、このファイルを編集するだけで済みますので、管理も楽になりそうです。

Step 5:各ページの <main> タグを <div> タグに修正する

layout.tsx 側で <main> タグを管理するようにしたため、各ページの page.tsx にある <main> タグと重複しないよう修正が必要です。

<main> タグは1ページに1つが HTML の基本ルールです。このまま放置すると <main> の中に <main> が入る入れ子になり、 SEO やアクセシビリティ上の問題が起きる可能性があります。各ページ側のタグを <div> に変更して対応します。

トップページ(app/page.tsx)の修正

nano ~/example-blog/app/page.tsx

ファイルを開いたら、一番上の方にある以下の行を探します。

<main className="max-w-3xl mx-auto p-8">

これを以下に書き換えます。

<div className="max-w-3xl mx-auto p-8">

あわせて、ファイルの末尾付近にある閉じタグ </main></div> に変更して保存します。

修正できたら、以下のコマンドで変更内容を確認できます。

grep -n "main\|div" ~/example-blog/app/page.tsx

<main> の行が消え、 <div> に置き換わっていれば修正完了です。

個別記事ページ(app/posts/[id]/page.tsx)の修正

nano ~/example-blog/app/posts/\[id\]/page.tsx

コマンドの \[id\] のように [] の前にバックスラッシュ(\)をつけているのは、ターミナル上では [ が特殊文字として扱われるためです。バックスラッシュをつけることで「ただの文字として扱ってください」という意味になります。

同じく <main><div> に、 </main></div> に変更して保存します。

Step 6:動作確認

すべての準備が整いました。 Next.js を起動してブラウザで確認します。

cd ~/example-blog
npm run dev

起動したら、ブラウザでサイトにアクセスします。以下の点を確認してください。

  • ページ上部にご自身のブログ名とナビゲーションが表示されているか
  • サイト名をクリックするとトップページに戻るか
  • ページ下部にコピーライトが表示されているか
  • トップページと個別記事ページ、どちらでもヘッダーとフッターが表示されているか
Next.jsで構築したサイトのトップページでヘッダーとフッターを表示させた画面の画像

トップページにブログ名と「ホーム」のナビゲーションが表示され、記事一覧の下にコピーライトのフッターが表示されています。

Next.jsで構築したサイトの個別記事でヘッダーとフッターを表示させた画像

個別記事でも、トップページと同様にヘッダーとフッターが表示されています。
ブログ全体の見た目を変えずに、トップページと個別記事を表示できるので、デザインに統一感が出て、とてもいい感じになります。

ヘッダーとフッターがすべてのページで表示されれば成功です。

Cursor の Simple Browser を使った確認が便利

今回の作業を通じて、 Cursor の「 Simple Browser 」という機能がとても便利だと感じました。

Cursor の画面上部のメニューから「 View 」→「 Command Palette 」( Ctrl + Shift + P )を開き、「 Simple Browser 」と入力して選択します。 URL に http://localhost:3000 を入力すると、エディタの中にブラウザが表示されます。

CursorのSimple Browserを開いて、エディタでコード編集をしながらサイトを確認できるようにした画面の画像

上のスクリーンショットは、 Cursor の画面を左右に分割してコードとブラウザを並べて表示している様子です。

コードを編集しながら隣でリアルタイムに確認できるので、ブラウザを別で開く手間が省けます。

開発モード(npm run dev)を使うと、画面の左下に Next.js の開発用ツールバーが表示されます。これは開発モードのみ表示される、デバッグ用のメニューです。

Next.jsの開発モードでサイトを開いたときに左下に表示されるデバッグメニューの画像

上のスクリーンショットは、画面左下に表示される Next.js の開発用ツールバーです。

  • Route: Static :現在のページが静的ページとして生成されていることを示している
  • Bundler: Turbopack : Next.js 15 から標準になった高速ビルドツールが動いていることを示している

本番用のビルド(npm run build)を実行すると自動的に消えるため、今は気にせず作業を進めて問題ありません。

まとめ

今回は、 Next.js の layout.tsx を使って、ヘッダーとフッターを全ページ共通のレイアウトとして実装する手順を解説しました。

components フォルダに部品を分けて作り、 layout.tsx{children} で差し込む構造は、最初は少し手間に感じるかもしれません。しかし今後、ナビゲーションを増やしたいときは Header.tsx<li> を追加するだけ、デザインを変えたいときは Tailwind CSS のクラス名を修正するだけで、全ページに一括で反映されます。

サイトとしての「外枠」が整ったことで、ようやくブログらしい見た目になってきました。

次回は、記事ごとに異なるタイトルやメタディスクリプション、アイキャッチ画像を Markdown のフロントマターから自動で読み込んで設定する、 SEO と OGP の対応を行います。

コメント

タイトルとURLをコピーしました