【個人開発】Next.jsでのWebサイト制作 #4　microCMSを使ったWebサイトへのBlog記事投稿

こんにちは、Naotoです。

Next.jsでのWebサイト制作 #4　では、microCMSを使ったWebサイトへのBlog記事投稿について紹介したいと思います。

## microCMSとは？
microCMSとは、APIベースの日本製ヘッドレスCMSです。

### ヘッドレスCMSとは？
ヘッドレスCMSとは、フロントエンド機能を持たず、バックエンド機能のみを備えたCMSのことです。
つまり、microCMSのGUI上でデータを登録し、フロントエンドからAPIを叩くことで、取得したデータを自由に画面上に表示することができます。（フロントエンドは自分で実装する必要があるため、画面に表示する際の自由度が高いです。）

https://microcms.io/

## 本Webサイトにおける使用例
本Webサイトにおいては、Blogページ、GalleryページにてmicroCMSを使用しました。

以下のように、microCMSの管理画面で投稿した記事を各コンポーネントで取得し、表示するといった処理をしています。

* microCMS管理画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/7fb8cce0-07ef-bf88-1bec-6f8ec76dfd4d.png)

* Blogページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/1037df31-6e23-b68f-4ff7-c1607feb9c7d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/cf40eab4-58c4-afac-2844-c549c2437219.png)

* Galleryページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/99a085cf-ce04-802c-bb34-1e693120a508.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/b0a6f3da-435e-99de-6108-318e0462cab2.png)


気づいた方もいると思いますが、Galleryページに掲載している画像は、Blogページの各記事のサムネと同じ画像になっております。

そのため、microCMSからのデータ取得方法も一緒となりますので、今回は、Blogページの実装方法のみ説明させていただきたいと思います。

## やってみよう！
では早速、microCMSにブログ記事を投稿し、Webブラウザに表示する手順を説明します。

### microCMSでのGUI操作
※アカウント作成方法は割愛させていただきます。

#### サービスの作成

①「一から作成する」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/ee9aca5f-6cf8-753a-c464-e163daedaeba.png)

②サービス名, サービスIDを入力。（なんでもOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/d6121bfd-b785-116a-94bb-42e6032feebe.png)


③「サービスにアクセスする」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/1b6fc16d-99c8-8027-b00e-36aba0b9c77c.png)

#### APIの作成

①「自分で決める」をクリック。（「ブログ」や「お知らせ」を選ぶとある程度自動でやってくれる。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/87af6697-2ff5-704b-7eef-16883cc9507a.png)

②API名, エンドポイントを入力。（なんでもOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/4258a0e8-491b-b37f-78b9-32be1bab86f2.png)

③API型を選択（今回はリストを選択）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/72dc341c-8f19-1684-47b9-15fe4dc4a493.png)

④APIスキーマを定義
ここでデータの構造を定義します。
今回はブログ記事のため、「タイトル」「写真」「本文」を定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/59038df1-a168-bc7c-55f5-0c4020f39382.png)

フロントエンド側でAPIを叩いた際は、以下のようなJSONが返ってきます。
※「id」~「revisedAt」はデフォルトで設定されています。
```
{
    contents: [
        {
        id: '9dl-1anaj_ml',
        createdAt: '2024-07-21T01:42:13.847Z',
        updatedAt: '2024-07-21T03:49:12.060Z',
        publishedAt: '2024-07-21T01:42:13.847Z',
        revisedAt: '2024-07-21T03:49:12.060Z',
        title: 'ここにタイトルのデータが入ってくる',
        photo: {
        ここに写真のデータが入ってくる。
        },
        body: 'ここに本文のデータが入ってくる。'
        },
        
        {
        他のブログ記事
        },
        
        {
        他のブログ記事
        },
    ],

}
```


#### 記事の投稿

①「＋追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/4ed6370c-0c39-2d37-f279-4c9391c10b88.png)

⑥記事の内容を各スキーマに入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/bdd8a1f0-5a3b-8890-2768-f7be89e4cdb1.png)

⑦公開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/0aa2ba44-8c5c-80e5-9577-b1e46bd02fe5.png)


#### 完了

上記ステップでmicroCMSへのブログ記事投稿は完了です。
とっても簡単です。


### フロントエンドからデータを取得する

では次に、microCMSにて公開したデータをフロントエンドで取得し、画面に表示する手順を説明します。

#### インストール
まず、microCMSを扱うには以下のインストールが必要です。
```bash
npm install microcms-js-sdk
```

#### client.jsの作成
次に、microCMSとプロジェクトを連携するために、プロジェクトフォルダ直下にlibs/client.jsを作成し、以下を実装します。

```ts
import { createClient } from "microcms-js-sdk";

if (!process.env.API_KEY) {
    throw new Error("API_KEY is not defined");
}

export const client = createClient({
    serviceDomain: "blog-guidance",
    apiKey: process.env.API_KEY
});

```

* serviceDomain
microCMS GUI上の、「API設定→基本情報→エンドポイント」に書かれている、
https://"ここの部分".microcms.io/api/v1/blog
を入力します。

* apiKey
microCMS GUI上の、「権限管理→APIキー」に書かれているキーを、
.envファイルに記載し、呼び出す。

#### 全ブログ記事のデータ取得＆表示
microCMSとプロジェクトの連携ができたら、いよいよデータを取得します。

microcms-js-sdkを利用することで、microCMS上の全ブログ記事のデータを以下のように取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/9e1ee895-cb07-35ae-1185-61179b55471d.png)
↑GUI上の「APIプレビュー」の画面

上記に倣ってデータを取得してみます。

※今回はSSRにてデータを取得しています。const revalidate = 0; を定義するだけで、SSRを使えます。
const revalidate = 60;　とすると６０秒間のISRとなります。
revalidateを定義しないと、SSGとなります。

↓詳しくは以下公式ドキュメントを参照ください。

https://blog.microcms.io/nextjs13-microcms-rsc/


それでは早速実装してみます！

以下は、本WebサイトのBlogコンポーネント（page.tsx）です。
ここで全ブログ記事のデータを取得し、子コンポーネントに渡します。

```ts
import { client } from "../../../libs/client";
import BlogList from "./BlogList";

// ブログページ

// SSR設定（MicroCMS独自の書き方)
export const revalidate = 0;

export default async function Blog() {
  let blog = [];
  let error = null;

  try {
    // microCMSからブログ情報を取得
    const data = await client.get({ endpoint: "blog" });
    blog = data.contents; //オブジェクトとして取得されるため、contentsフィールドのみ取得
  } catch (err) {
    console.error("Failed to fetch blog data:", err);
    error = "Failed to fetch blog data. Please try again later.";
  }

  return (
    <div className="container mx-auto p-5">
      {/* タイトル */}
      <h1 className="m-2 md:m-4 font-bold text-gray-100 text-3xl lg:text-5xl italic">
        🥍 Blog 🥍
      </h1>
      {error ? (
        <p className="text-red-500">{error}</p>
      ) : (
      // 取得したデータを子コンポーネントに渡す。
        <BlogList blog={blog} />　　
      )}
    </div>
  );
}
```

上記にて、ブログ記事データをJSON形式で取得し、子コンポーネントに渡すことができました。

次に、子コンポーネントで受け取った全ブログ記事のデータを表示してみましょう。

※以下JSX部分の抜粋。

```tsx
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-colos-3 lg:grid-cols-4 xl:grid-cols-5 gap-6 ">
        {/* 全ブログ記事のデータを展開 */}
        {blog.map((blog: any, index: number) => (
          <div key={blog.id}>
              <article className="bg-yellow-300 text-black shadow-lg rounded-lg overflow-hidden h-auto border-4 border-black hover:border-yellow-500">
                {/* 個々のブログへのリンク */}
                <Link href={`blog/${blog.id}`}>
                  <div className="relative">
                    <img
                      src={blog.photo.url}
                      alt={blog.title}
                      className="w-full h-64 object-cover"
                    />
                    <div className="p-6 h-40 relative">
                      <h3 className="text-xl font-semibold">{blog.title}</h3>
                      <p className="text-xs sm:text-sm md:text-base text-gray-600 absolute bottom-5">
                        {formatDate(blog.publishedAt)}
                      </p>
                    </div>
                  </div>
                </Link>
              </article>
          </div>
        ))}
      </div>
```
上記のように、受け取ったデータをmap関数で展開し、「blog.id」「blog.title」のようにして画面に出力しています。
そして、それぞれのarticleにLinkタグをつけ、個々のブログページ"blog/blog.id"に遷移されるようにしています。


すると、以下のように全ブログ記事のデータが画面上に表示されるようになりました！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/579b02b3-fb35-bf3c-0d75-771684ec7069.png)

#### 個々のブログ記事のデータ取得＆表示

個々のブログ記事のデータ取得方法は、全ブログ記事のデータの取得方法と大きく変わらず、
エンドポイントの後ろに個々のidをつけることでデータを取得できます。

{endpoint}/{content_id}

画面への表示方法も同じですので、説明は割愛します。
ぜひ個々のブログページも作成してみてください。


## 最後に

最後までお読みいただき、ありがとうございました。

今回はBlogページをもとに、microCMSを使ってWebサイトにBlog記事を投稿する方法について紹介しました。
Webサイトには、Blog記事の他にも、 Newsなど定期的に発信したいコンテンツが盛り込まれることが多いと思います。

ぜひそういった際には、microCMSを使ってみてはいかがでしょうか。


次回は、Contactページにおける、Email JSを使った問合せフォームの作成方法について紹介する予定です。
ぜひ読んでいただければ幸いです。

ありがとうございました！！！