Next.js(App Router)とmicroCMSでブログを作ろう!! ~カテゴリ機能編~

今回は、前回作成したブログサイトにカテゴリ機能を実装してみる。 なお、前回の記事通りに作成した場合、すでにAPIの方のカテゴリ機能は実装されているはずなので、今回はそれを利用する。

カテゴリ一覧のコンポーネントを作成

今回のカテゴリ一覧のように、将来的にいろんな場所で使う可能性のある機能はコンポーネントに切り出し、共通パーツ化した方が何かと便利なので、まずはコンポーネントを作成することから始める。

プロジェクト内に「/app/component/CategoryLinks.jsx」ファイルを作成し、いったん以下のように記述し、正しくコンポーネントとして呼び出せるかを確認する。

export default async function StaticPage() {
  return (
    <div>
      <h2>カテゴリ一覧</h2>
    </div>
  );
}

app直下のpage.jsxから呼び出してみる

  import Link from "next/link";
  import CategoryLinks from "./component/CategoryLinks";

  // 省略

  return (
    <div>
      <ul>
        {contents.map((post) => {
          return (
            <li key={post.id}>
              <Link href={`/blog/${post.id}`}>{post.title}</Link>
            </li>
          );
        })}
      </ul>
      // CategoryLinksコンポーネントを呼び出し
      <CategoryLinks />
    </div>
  );

画面に「カテゴリ一覧」というタイトルが表示されていることを確認したら次のステップへ

カテゴリ一覧を取得

/lib/microcms.jsに以下のメソッドを追加

// カテゴリ一覧を取得
export const getCategories = async () => {
  const categories = await client.getAllContents({
    endpoint: "categories"
  });

  return categories;
};

CategoryLinksコンポーネントでいま作成したメソッドを呼び出し

import { getCategories } from "../../lib/microcms";

export default async function StaticPage() {
  const categories = await getCategories();

  return (
    <div>
      <h2>カテゴリ一覧</h2>
      <ul>
        {categories.map((category) => {
          return (
            <li key={category.id}>
              <p>{category.name}</p>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

先ほど確認した「カテゴリ一覧」のタイトルの下に各カテゴリの名称が表示されていればOK

カテゴリごとの記事一覧ページを作成

最後にカテゴリ一覧からカテゴリを選択すれば、そのカテゴリの記事一覧を取得できるようにする。 ※検証用のサンプル記事を事前にmicroCMSの管理ページでいくつか作っておくこと!!

まずはページの作成、「app/category/[id]/page.jsx」のファイルを作成。 基本的にはapp直下のpage.jsxを流用しつつ、記事の取得方法を変更し、以下のようになる。

import Link from "next/link";
import CategoryLinks from "../../component/CategoryLinks";
import { getList } from "../../../lib/microcms";

export default async function StaticPage({
  params: { id },
}) {
  const { contents } = await getList({ filters: `category[equals]${id}` } );

  if (!contents || contents.length === 0) {
    return <h1>No contents</h1>;
  }

  return (
    <div>
      <ul>
        {contents.map((post) => {
          return (
            <li key={post.id}>
              <Link href={`/blog/${post.id}`}>{post.title}</Link>
            </li>
          );
        })}
      </ul>
      <CategoryLinks />
    </div>
  );
}

そして、カテゴリ一覧コンポーネントにリンクを張る。

{/* 抜粋 */}
<ul>
  {categories.map((category) => {
    return (
      <li key={category.id}>
        <Link href={`/category/${category.id}`}>{category.name}</Link>
      </li>
    );
  })}
</ul>

各カテゴリのタイトルをクリックして、そのカテゴリの記事一覧が表示できれば完了。

次はワード検索の実装を予定しています。