microCMSとNext.jsを使って記事を作る
従来のCMS(WordPressのようなものを想定)を使うにはHTMLをparseしたり、MarkdownをparseしたりしないといけなかったりしてNext.jsと一緒に使うには僕は使いづらいと思っている。
そこで、microCMSで、記事のパーツを配列として吐き出してくれるAPIを作ってる
次にNext.js側で構造化したデータをComponentに割り当てていく
そんな作りで上手くできないか。
ということで試し続けるスクラップ
- microCMSのアカウントを作成
- 以下のように記事APIを作成
- articlesに構造化した記事を入れていく想定
- ほかはメタデータを入れるスキーマを定義
- 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(実装完了したら書く)
TrackOnClick
TrackOnViewContent