0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsとmicroCMSを連携してみる

Posted at

メモ
インフラエンジニアなので、どうもフロントエンド系は苦手だ・・・
公式ドキュメントとにらめっこしていくしかない。

環境イメージ

nextjs.drawio.png

microCMSの登録

無料で始めるを押下。

image.png

登録後、以下のような画面になる。
1から作成するを押下。
image.png

image.png

image.png

ブログを指定します。
image.png

以下のような設定画面が表示されます。
image.png

画面左上の歯車マークからAPIキーがあることを確認します。
image.png

Next.jsでアプリ作成

NEXT.jsコンテナ側で.env.localファイルを作成。
この中にAPIキー等を記載する。

root@2c0e580ef479:/my-app# apt install -y vim
root@2c0e580ef479:/my-app# ls
README.md  eslint.config.mjs  next.config.ts  package-lock.json  postcss.config.mjs  tsconfig.json
app        next-env.d.ts      node_modules    package.json       public
root@2c0e580ef479:/my-app# vi .env.local
root@2c0e580ef479:/my-app# cat .env.local
# .env.local
MICROCMS_SERVICE_DOMAIN=あなたのサービスID(https://xxxx.microcms.io の xxxx の部分)
MICROCMS_API_KEY=あなたのAPIキー

SDKをインストール

root@2c0e580ef479:/my-app# npm install microcms-js-sdk

以下を作成していきます。
page.tsxにNEXT.jsのホーム画面を出力するコンポーネントが記載されている。

root@2c0e580ef479:/my-app# mkdir libs
root@2c0e580ef479:/my-app# touch libs/microcms.ts
root@2c0e580ef479:/my-app# vi libs/microcms.ts
root@2c0e580ef479:/my-app# cat libs/microcms.ts
// libs/microcms.ts
import { createClient } from "microcms-js-sdk";

export const client = createClient({
  serviceDomain: process.env.MICROCMS_SERVICE_DOMAIN || "",
  apiKey: process.env.MICROCMS_API_KEY || "",
});

root@2c0e580ef479:/my-app# cp -p app/page.tsx app/page.tsx.org
root@2c0e580ef479:/my-app# vi app/page.tsx
root@2c0e580ef479:/my-app# cat app/page.tsx
import { client } from "@/libs/microcms";
import Link from "next/link"; // ← 追加:リンク機能を使うためのインポート

// 型定義
type Blog = {
  id: string;
  title: string;
  content: string;
  eyecatch?: { 
    url: string;
    width: number;
    height: number;
  };
};

export default async function Home() {
  const { contents } = await client.getList<Blog>({
    endpoint: "blogs", 
  });

  return (
    <main style={{ padding: "20px" }}>
      <h1>ブログ一覧</h1>
      <ul>
        {contents.map((post) => (
          <li key={post.id} style={{ marginBottom: "40px" }}>
            {/* ▼ リンクで囲む修正:ここから ▼ */}
            {/* href="/blog/記事ID" というURLへ移動するように設定します */}
            <Link href={`/blog/${post.id}`}>
              
              {/* カーソルを合わせた時にクリックできるとわかるようにスタイル調整 */}
              <div style={{ cursor: "pointer" }}>
                <h2>{post.title}</h2>

                {post.eyecatch && (
                  <img
                    src={post.eyecatch.url}
                    alt={post.title}
                    width={300}
                    style={{ borderRadius: "8px" }}
                  />
                )}
              </div>
            </Link>
            {/* ▲ リンクで囲む修正:ここまで ▲ */}

            <div style={{ marginTop: "10px", color: "#666" }}>
              記事ID: {post.id}
            </div>
          </li>
        ))}
      </ul>
    </main>
  );
}

ここの内容はmicroCMSの各種記事のAPIプレビューの内容を翻訳しているようなイメージ。

// microCMSから取得する型
type Blog = {
  id: string;
  title: string;
  content: string;
  eyecatch?: { 
    url: string;
    width: number;
    height: number;
  };
};

image.png

endpointはmicroCMSの以下の部分のエンドポイントから確認することが出来ます。
microCMSの「blogs」というAPIから記事の一覧を取得する処理になる。

  const { contents } = await client.getList<Blog>({
    endpoint: "blogs", // または "news" など、microCMSで作ったエンドポイント名
  });

image.png

root@2c0e580ef479:/my-app# mkdir -p app/blog/[id]/
root@2c0e580ef479:/my-app# touch app/blog/[id]/page.tsx
root@2c0e580ef479:/my-app# vi app/blog/[id]/page.tsx
root@2c0e580ef479:/my-app# cat app/blog/[id]/page.tsx
import { client } from "@/libs/microcms";

// 型定義
type Blog = {
  id: string;
  title: string;
  content: string;
  eyecatch?: {
    url: string;
    width: number;
    height: number;
  };
  publishedAt: string;
};

export default async function BlogPostPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;

  // microCMSから、そのIDの記事を1つだけ取得する (getListDetail)
  const post = await client.getListDetail<Blog>({
    endpoint: "blogs",
    contentId: id,
  });

  return (
    <main style={{ padding: "20px", maxWidth: "800px", margin: "0 auto" }}>
      {/* タイトル */}
      <h1 style={{ fontSize: "2rem", marginBottom: "10px" }}>{post.title}</h1>

      {/* 日付(あれば) */}
      <p style={{ color: "#888", marginBottom: "20px" }}>
        公開日: {new Date(post.publishedAt).toLocaleDateString()}
      </p>

      {/* アイキャッチ画像 */}
      {post.eyecatch && (
        <img
          src={post.eyecatch.url}
          alt={post.title}
          width="100%"
          style={{ borderRadius: "8px", marginBottom: "30px" }}
        />
      )}

      {/* ▼ 本文(HTML)を表示する重要な部分 ▼ */}
      <div
        dangerouslySetInnerHTML={{ __html: post.content }}
        // ※注意: 本来はCSSでスタイル調整が必要です
      />
    </main>
  );
}

image.png

image.png

MicroCMSでコンテンツを追加するとAPI経由でNext.js上でも表示されることがわかります。
CSSで指定していないので、記事サムネイルが縦並びになっていますが、修正すれば横に並べることも可能でしょう。
当方インフラエンジニアなので、すぐに修正は出来ませんが。
image.png

参考になりそうな公式ドキュメント

getList

getListDetail

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?