Astro を使って国産ヘッドレス CMS 3製品の接続方法を比較してみた
この記事は CMS(WordPressやヘッドレスCMS) Advent Calendar 2022の23日の記事です。
Astro と国産ヘッドレス CMS との接続方法をまとめてみました。
TL;DR
国産3種類のヘッドレスCMSを利用してブログサイトを想定したページを作成しました。
正直、Astro で構築する範囲では全てのサービスに同じ程度の実装量かなーというのが感想です。静的サイトでの運用を考えると、スラッグ・エイリアス機能のある Spearly / microCMS を利用したほうが覚えやすい URL を生成しやすそうでした。
Pros.Cons. | Spearly | microCMS | Newt |
---|---|---|---|
無料プラン | 〇 | 〇 | 〇 |
REST API | 〇 | 〇 | 〇 |
SDK JS | 〇 | 〇 | 〇 |
SDK JS(TypeScript)(※1) | 〇 | △ | △ |
スラッグ(※2) | 〇 | 〇 | × |
WebHook | 〇 | 〇 | 〇 |
※1 : 全て TypeScript に対応していますが、Spearly 以外は、コンテンツ取得後の型が any
となり、型エラーの検出が難しかったです。
※2 : 静的サイトのファイル名にコンテンツを識別するためのIDをスラッグとして利用しています。Newt だけがスラッグの概念が無く、固有の識別子 _id
を利用しています。そのためファイル名が 63a5520c2469ac525533db32.html
のように内容が推測できないものになっちゃいました。
Astro ?
Astro と Spearly を使ったボイラープレート の紹介を参照してください。
一言でいうと静的サイトジェネレーターです!
検証する CMS
今回は、REST API が使える&無料で使える日本製の CMS を対象とています。
microCMS と Newt のフリープランの比較は【ヘッドレスCMS】microCMS と Newt を比較に詳細が書かれています。Spearly の情報が無かったのでフリープランがどうなるか3製品で比較してみました。
Spearly CMS(Free) | microCMS (Hobby) | Newt (Free) | |
---|---|---|---|
料金 | 無料 | 無料 | 無料 |
APIリクエスト数 | 無制限 | 無制限 | 2,000,000 |
データ転送量 (月毎) | 25GB | 20GB | 100GB |
コンテンツ数 | 無制限 | 10,000件 | 無制限 |
1メディアあたりの容量 | 無制限 | 40MB | 50MB |
API数 | 無制限 | 3個 | 無制限 |
APIキー数 | 1個 | 1個 | 1個 |
メンバー数 | 1人 | 3人 | 無制限 |
Spearly CMS (スピアリー)
国産の CMS ヘッドレスです。扱いやすいシンプルな機能です。埋め込みの簡単な JavaScript タグが用意されていたり、さくらインターネットの「ImageFlux」を使って WebP として画像を配信したりできます。
- 無料プランあり (管理者1人まで。月の API 転送量の上限あり[25GB])
- REST API あり
- 記事リストの取得
- 記事単体の取得
- サイトを「プロジェクト」という単位で作成する
- サイト内のコンテンツは「コンテンツ」として管理する
- SDK JS ライブラリは TypeScript の型がエクスポートされていて実装しやすいと思います。
- コンテンツを識別するために「エイリアス」を利用します。
SDK JS:
microCMS
有名どころなので、紹介は不要だと思います。コンテンツの更新や削除などできるようですが、今回は簡単なコンテンツ取得だけを利用します。
- 無料プランあり
- REST API あり
- 記事リストの取得
- 記事単体の取得
- コンテンツの削除変更が可能
- API キーの種類で公開・未公開の取得切り替えが可能
- サイトは「サービス」という単位で作成する
- サイト内コンテンツは「コンテンツ(API)」として管理する
- コンテンツを識別するために「Id」を利用します
SDK JS:
Newt (ニュート)
国産で2021年に始まったスタートアップのヘッドレス CMS です。
- 無料プランあり
- REST API あり
- 記事リストの取得
- 記事単体の取得
- API キーの種類で公開・未公開の取得切り替えが可能(プレビューは実装予定)
- サイトを「アプリ」として管理し、サイト内コンテンツは「モデル」として管理する
SDK JS:
その他国産 CMS
色々ありますが、以下のものは今回は検証の対象外としました。
- kuroco :国内導入事例も多いです。設定が豊富ですが準備までに時間がかかるので今回は対象外としました。
- HeartCore CMS : 国内CMSシェアNo.1らしいです。無料プランが無かったので、今回は対象外としました。
Astro との通信検証
今回は、Astro で記事リストを作る通信方法を検証してみます。
検証に関して、以下のページを参考にしています。
Spearly CMS
Spearly はコンテンツを API クライアント経由で取得します。await spearlyApiClient.getList("blog")
を実行することで、コンテンツのリストを取得できます。
あとは、表示コンテンツに合わせてフォーマットし直すことでリスト表示できるようになります。
---
import { spearlyApiClient } from "../lib/spearly"
const contents = await spearlyApiClient.getList("blog")
const posts = contents.data.map(c => {
const title = c.attributes.fields.data.find(f => f.attributes.identifier === "title")
const description = c.attributes.fields.data.find(f => f.attributes.identifier === "description")
const date = c.attributes.fields.data.find(f => f.attributes.identifier === "date")
const image = c.attributes.fields.data.find(f => f.attributes.identifier === "image")
const alias = c.attributes.contentAlias
return {
title: title?.attributes.value,
alias,
description: description?.attributes.value,
date: date?.attributes.value,
image: image?.attributes.value
}
})
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Blog</title>
</head>
<body>
<h1>My Blog</h1>
<ul>
{posts.map((post) => (
<li>
<img src={`${post.image}`} alt={`${post.description}`} />
<a href={`/posts/${post.alias}/`}>
<h2>{post.title}</h2>
</a>
<time>{post.date}</time>
<p>{post.description}</p>
</li>
))}
</ul>
</body>
</html>
ボイラープレートは以下のレポジトリにあるのでご自由にお使いください。
microCMS
Spearly と同じく、コンテンツを API クライアント経由で取得します。await microcmsApiClient.getList({endpoint: 'blogs'})
を実行することで、コンテンツのリストを取得できます。
あとは、表示コンテンツに合わせてフォーマットし直すことでリスト表示できるようになります。
---
import { microcmsApiClient } from "../lib/microcms"
const contents = await microcmsApiClient.getList({endpoint: 'blogs'})
const posts = contents.contents.map(c => {
const title = c.title
const description = c.description
const date = c.date
const image = c.image.url
const alias = c.id
return {
title,
alias,
description,
date,
image,
}
})
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Blog</title>
</head>
<body>
<head>
</head>
<h1>My Blog</h1>
<section class="container">
<ul>
{posts.map((post) => (
<li>
<figure>
<img src={`${post.image}`} alt={`${post.description}`} />
</figure>
<a href={`/posts/${post.alias}/`}>
<h2>{post.title}</h2>
</a>
<time>{post.date}</time>
<p>{post.description}</p>
</li>
))}
</ul>
</section>
</body>
</html>
Spearly 同様以下のレポジトリにボイラープレートを用意しているのでお使いください。
Newt
Newet も他の CMS 同様ですが、WordPressのスラッグ、Spearly/microCMS のようなエイリアス・Id という別名の概念が無いため、デフォルトの識別子である _id
を利用しています。
---
import { newtApiClient } from "../lib/newt"
const contents = await newtApiClient.getContents({
appUid: "blog",
modelUid: "blog"
})
const posts = contents.items.map(c => {
console.log(c)
const title = c.title
const description = c.description
const date = c.date
const image = c.image.url
const alias = c._id
return {
title,
alias,
description,
date,
image,
}
})
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Blog</title>
</head>
<body>
<head>
</head>
<h1>My Blog</h1>
<section class="container">
<ul>
{posts.map((post) => (
<li>
<figure>
<img src={`${post.image}`} alt={`${post.description}`} />
</figure>
<a href={`/posts/${post.alias}/`}>
<h2>{post.title}</h2>
</a>
<time>{post.date}</time>
<p>{post.description}</p>
</li>
))}
</ul>
</section>
</body>
</html>
こちらも他のCMS同様にボイラープレートを用意しています。
まとめ
実装してみて分かったこととしては以下のような事です。
- どの CMS も接続方法には差が無さそう
- Newt はスラッグが見当たらなくページアドレスが自動生成されたもので分かりにくくなるかもしれない
- Spearly の SDK JS が優秀
Astro を使ってヘッドレス CMS のブログ運用を行うのであれば、構築にさほど時間はかからないのではないかというのが感想です。Newt だけがスラッグが無いので分かりやすいアドレスの運用が難しいかもしれません。
ぜひ、みなさんも Astro + Spearly などを使ったブログの運用を試してみてください!
Discussion