Open7

microCMSとNext.jsを使って記事を作る

かいとかいと

従来のCMS(WordPressのようなものを想定)を使うにはHTMLをparseしたり、MarkdownをparseしたりしないといけなかったりしてNext.jsと一緒に使うには僕は使いづらいと思っている。

そこで、microCMSで、記事のパーツを配列として吐き出してくれるAPIを作ってる
次にNext.js側で構造化したデータをComponentに割り当てていく
そんな作りで上手くできないか。
ということで試し続けるスクラップ

かいとかいと
  1. microCMSのアカウントを作成
  2. 以下のように記事APIを作成
  • articlesに構造化した記事を入れていく想定
  • ほかはメタデータを入れるスキーマを定義
  1. articlesに定義するためのカスタムフィールドを作成
    ここに記事のパーツのスキーマを定義していく想定
    基本的に一つのフィールド=一つのComponentになっていて、Componentに必要なデータをここで渡せるようにする

ここまでできたらNext.js側の処理を作って足らないものはあとから追加していくことにする

かいとかいと

fetchについてはmicroCMSにもプレビューがあるようにヘッダーにKEYを付けてGETするだけなので詳細hあ省く。

microCMSの記事-articleの中身をComponentにおいていきたいので以下のようにした

export const Content = ({ article }: { article: ArticleType['article'] }) => {
  return article.map((content) =>
    match(content)
      .with({ fieldId: "richEditor" }, RichText)
      .with({ fieldId: "heading" }, Heading)
      .exhaustive()
  );
}

シンプルにarticleをmapで回してComponentに割り振っていく
microCMSではfieldIdに自分で設定したものを入れてくれるのでそれを条件に条件分岐させている。
ここではts-patternを使っている

かいとかいと

opengraph-imageを作る

import { getArticleById } from "@/service/microcms/get-article-by-id";
import { ImageResponse } from "next/og";

// Image metadata
export const size = {
  width: 1200,
  height: 630,
};

export const runtime = 'edge'

export const contentType = "image/png";

const Image = async ({ params: { id } }: { params: { id: string } }) => {
  const article = await getArticleById(id);
  if (!article?.title) return null;
  const title = article.title;


  try {
    return new ImageResponse(
      <div
        style={{
          backgroundColor: "#000",
          backgroundSize: "100% 100%",
          height: "100%",
          width: "100%",
          display: "flex",
          textAlign: "left",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <div
          style={{
            backgroundColor: "#fff",
            backgroundSize: "100% 100%",
            height: "90%",
            width: "95%",
            display: "flex",
            textAlign: "left",
            alignItems: "flex-start",
            justifyContent: "center",
            flexDirection: "column",
            flexWrap: "nowrap",
          }}
        >
          <div
            style={{
              width: "100%",
              fontSize: 60,
              fontStyle: "normal",
              fontWeight: "bold",
              color: "#000",
              padding: "0 120px",
              lineHeight: 1.3,
              marginBottom: "30px",
              wordWrap: "break-word",
            }}
          >
            {title}
          </div>
          <div
            style={{
              width: "100%",
              fontSize: 40,
              fontStyle: "normal",
              fontWeight: "bold",
              color: "#000",
              padding: "0 120px",
              lineHeight: 1.3,
            }}
          >
            ✏️ サイトタイトルとかいれよう
          </div>
        </div>
      </div>,
      {
        ...size,
      },
    );
  } catch (error) {
    console.log(error);
    return null;
  }
}


export default Image

かいとかいと

構造化したAPIで記事を作ったとしても、主に文章の装飾でリッチエディタを使いたいのは変わらない。

ただ、microCMSのリッチエディタで記事を書いたとき、出力はHTML固定になっている。

今回はNext.jsでComponentとして扱いたいので、HTMLを直接出力はしたくないので困っている。
そこで、HTMLをパースして、JSXに変換するためのHTMLtoJSXの処理を作ることにした。

wip

かいとかいと

Next.jsで画像を扱うパート2

画像を返してくれるAPIを作る

wip(実装完了したら書く)