monaka

Next.jsでサイドメニューにカテゴリ・タグ一覧を作る

全ページ共通で表示するサイドメニューを作る。今回もmicroCMSとNext.jsの環境で作成していく。

完成系イメージ

microCMSのAPIに登録しているカテゴリ、タグを全件取得して表示する。

API側に入稿したら自動でカテゴリやタグが増えるイメージだ。WordPressなどの一般的にCMSなどに標準的に備わっている機能をNext.jsとmicroCMSでも再現した。遷移先のカテゴリ一覧、タグ一覧ページは事前に作っている。カテゴリ一覧は本を参考に作っていて、自作したのはタグなのでタグ一覧ページの作り方は以下にまとめている

参考:Next.jsでタグ機能を作る

サイドメニューコンポーネントを追加

サイドメニューコンポーネントに以下のように追記した。Category, Tagをインポートしたのと、リンクもインポートしている。

// app_components/SideMenu/index.tsx
import type { Category, Tag } from "@/app/_libs/microcms"; // Category,Tag型をインポート
import SearchField from "../SearchField";
import styles from "./index.module.css";
import Link from "next/link";

type Props = {
  categories: Category[]; // カテゴリの配列をCategory型に変更
  tags: Tag[]; // タグの配列をTag型に変更
};

export default function SideMenu({ categories, tags }: Props) {
  return (
    <>
      <SearchField />
      <h3 className={styles.sidetitle}>カテゴリ</h3>
      <ul>
        {categories.map((category) => (
          <li key={category.id} className={styles.categorylist}>
            <Link
              key={category.id}
              href={`/blog/category/${category.id}`}
              className={styles.categorylink}
            >
              {category.name}
            </Link>
          </li>
        ))}
      </ul>
      <h3 className={styles.sidetitle}>タグ</h3>
      <ul className={styles.tagContainer}>
        {tags &&
          tags.map((tag) => (
            <li key={tag.id} className={styles.taglist}>
              <Link
                key={tag.id}
                href={`/blog/tag/${tag.id}`}
                className={styles.taglink}
              >
                {tag.name}
              </Link>
            </li>
          ))}
      </ul>
    </>
  );
}

layout.tsxを修正する

今回、サイドメニューコンポーネントを読み込んでいる「layout.tsx」を修正した。取得したデータを反映するために以下のようにしている

import "./globals.css";
import { GoogleTagManager } from "@next/third-parties/google";

import type { Metadata } from "next";
import Header from "./_components/Header";
import Footer from "./_components/Footer";
import SideMenu from "./_components/SideMenu";
import {
  getAllCategoryList,
  getAllTagList,
  type Category,
  type Tag,
} from "./_libs/microcms";

export const metadata: Metadata = {
  metadataBase: new URL("https://monaka496.com"),
  title: {
    template: "%s | monaka",
    default: "monaka",
  },
  description: "日々の学びをアウトプットするブログです。",
  openGraph: {
    title: "monaka",
    description: "日々の学びをアウトプットするブログです。",
    images: ["/ogp.png"],
  },
};

// カテゴリ・タグリスト
async function getData() {
  const categories = await getAllCategoryList(); // カテゴリデータを取得
  const tags = await getAllTagList(); // タグデータを取得
  return { categories, tags };
}

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const { categories, tags } = await getData(); // カテゴリ・タグデータを取得

  return (
    <html lang="ja">
      <body>
        <Header />
        <div className="layout">
          <main className="content">{children}</main>
          <aside className="sidemenu">
            <SideMenu categories={categories} tags={tags} />
          </aside>
        </div>
        <Footer />
      </body>
      <GoogleTagManager gtmId="GTM-XXXXXXXX" />
    </html>
  );
}

デザインの調整

microCMSブログのデザインを目標に作成しているので以下のようにしている。参考までに

.sidetitle {
  background-color: #eee;
  border-radius: 5px;
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 10px;
  padding: 6px 10px;
}
.categorylist {
  border-bottom: 1px solid #eee;
}
.categorylink {
  display: block;
  padding: 10px;
}
.tagContainer {
  padding: 0 10px;
}
.taglist {
  display: inline-block;
  margin-right: 16px;
  padding: 4px 0;
}
.taglink {
  font-size: 16px;
  padding-left: 18px;
  position: relative;
}
.taglink::before {
  background: url(/icon_tag_side.svg) 50% no-repeat;
  background-size: contain;
  content: "";
  display: inline-block;
  height: 14px;
  left: 0;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
}

参考にしたサイト

Next.js+ヘッドレスCMSではじめる! かんたんモダンWebサイト制作入門 高速で、安全で、運用しやすいサイトのつくりかた
Next.js+ヘッドレスCMSではじめる! かんたんモダンWebサイト制作入門 高速で、安全で、運用しやすいサイトのつくりかた
Amazon楽天市場Yahoo!ショッピング

関連記事