@shinyaz

Next.js ブログにカテゴリ一覧・タグ一覧ページを追加する

約3分
目次

課題

このブログには個別のカテゴリページ(/ja/category/programming)とタグページ(/ja/tag/nextjs)があったが、全カテゴリ・全タグを俯瞰する手段がなかった。記事のバッジからは個別ページに遷移できるものの、「このブログにはどんなコンテンツがあるのか」を把握する一覧ページが存在しない。

両ロケールにカテゴリ一覧とタグ一覧のページを追加したかった。

データ層のコード追加はゼロ

この実装で満足だったのは、必要な関数がすべて src/lib/posts.ts に既存だったことだ:

  • getAllCategories() — 全カテゴリオブジェクトの取得
  • getCategoryName() / getCategoryDescription() — バイリンガル対応の名前・説明
  • getPostsByCategory() — カテゴリ別記事取得(件数カウント用)
  • getAllTags(locale) — ロケール別の全タグ取得
  • getPostsByTag() — タグ別記事取得(件数カウント用)

新しいユーティリティも、新しいコンポーネントも、新しいデータ取得パターンも不要。既存の関数を新しいページに組み合わせるだけだった。データ層を最初にきちんと設計した成果が出た形だ。

カードグリッド vs タグクラウド:なぜ異なるレイアウトか

2つの一覧ページは異なるレイアウトを使っている。理由はデータの形の違いにある。

カテゴリ一覧 はカードグリッド(grid gap-4 sm:grid-cols-2)。各カテゴリには名前・説明・記事数という構造化データがあり、カード形式に自然に収まる。カテゴリ数は少ない(現在1つ)ので、各カテゴリに視覚的な存在感を持たせたい:

TypeScript
<Link className="rounded-lg border border-border p-4 transition-colors hover:bg-accent">
  <h2 className="font-semibold">{name}</h2>
  <p className="mt-1 text-sm text-muted-foreground">{description}</p>
  <p className="mt-2 text-xs text-muted-foreground">{postCount}件の記事</p>
</Link>

タグ一覧 はフレックスのタグクラウド。タグは説明のないフラットな文字列 — 名前と件数だけ。数が多いので密なレイアウトが合う:

TypeScript
<Link className="inline-flex items-center gap-1.5 rounded-full border border-border px-3 py-1.5 text-sm">
  #{tag} <span className="text-xs">({postCount})</span>
</Link>

タグクラウドのバッジは既存の TagBadgepx-2.5 py-0.5 text-xs)より意図的に大きくし(px-3 py-1.5 text-sm)、一覧ページでの視認性とタップしやすさを確保している。

ロケールの非対称性

設計上の微妙な違いとして、getAllTags(locale) はロケールを引数に取るが、getAllCategories() は取らない。これは定義方法の違いを反映している:

  • カテゴリ は静的 YAML ファイル — ロケールに関係なく同じカテゴリが存在し、name / nameJadescription / descriptionJa でバイリンガル対応
  • タグ は記事フロントマターのフリーテキスト — 日本語記事と英語記事でまったく異なるタグセットになりうる

つまりタグ一覧はロケールごとに異なるコンテンツを表示でき、カテゴリ一覧は同じカテゴリを翻訳された名前で表示する。バイリンガルなコンテンツシステムを作る際に重要な区別だ。

まとめ

  • 既存の関数がきれいに組み合わさる — データ層のコード追加ゼロで新ページが作れたのは、posts.ts のヘルパー関数設計が正しかった証拠だ。抽象化が適切なら、新機能はコンポジションだけで済む。
  • データの形がレイアウトを決める — カテゴリ(構造化、少数)→ カードグリッド、タグ(フラット、多数)→ タグクラウド。根本的に異なるデータに同じレイアウトを強制しないこと。
  • 静的 vs 動的メタデータの設計含意 — YAML 定義のカテゴリはロケール非依存、フロントマターのタグはロケール依存。この非対称性がバイリンガル一覧ページに影響する。

共有する

田原 慎也

田原 慎也

ソリューションアーキテクト @ AWS

AWS ソリューションアーキテクトとして金融業界のお客様を中心に技術支援をしており、クラウドアーキテクチャや AI/ML に関する学びをこのサイトで発信しています。このサイトの内容は個人の見解であり、所属企業の公式な意見や見解を代表するものではありません。

関連記事