📚

Astro を使って国産ヘッドレス CMS 3製品の接続方法を比較してみた

2022/12/23に公開

この記事は 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 (スピアリー)

https://cms.spearly.com/

国産の CMS ヘッドレスです。扱いやすいシンプルな機能です。埋め込みの簡単な JavaScript タグが用意されていたり、さくらインターネットの「ImageFlux」を使って WebP として画像を配信したりできます。

  • 無料プランあり (管理者1人まで。月の API 転送量の上限あり[25GB])
  • REST API あり
    • 記事リストの取得
    • 記事単体の取得
  • サイトを「プロジェクト」という単位で作成する
  • サイト内のコンテンツは「コンテンツ」として管理する
  • SDK JS ライブラリは TypeScript の型がエクスポートされていて実装しやすいと思います。
  • コンテンツを識別するために「エイリアス」を利用します。

SDK JS:
https://www.npmjs.com/package/@spearly/sdk-js

microCMS

https://microcms.co.jp/

有名どころなので、紹介は不要だと思います。コンテンツの更新や削除などできるようですが、今回は簡単なコンテンツ取得だけを利用します。

  • 無料プランあり
  • REST API あり
    • 記事リストの取得
    • 記事単体の取得
    • コンテンツの削除変更が可能
  • API キーの種類で公開・未公開の取得切り替えが可能
  • サイトは「サービス」という単位で作成する
  • サイト内コンテンツは「コンテンツ(API)」として管理する
  • コンテンツを識別するために「Id」を利用します

SDK JS:
https://www.npmjs.com/package/microcms-js-sdk

Newt (ニュート)

https://www.newt.so/

国産で2021年に始まったスタートアップのヘッドレス CMS です。

  • 無料プランあり
  • REST API あり
    • 記事リストの取得
    • 記事単体の取得
  • API キーの種類で公開・未公開の取得切り替えが可能(プレビューは実装予定)
  • サイトを「アプリ」として管理し、サイト内コンテンツは「モデル」として管理する

SDK JS:
https://www.npmjs.com/package/newt-client-js

その他国産 CMS

色々ありますが、以下のものは今回は検証の対象外としました。

  • kuroco :国内導入事例も多いです。設定が豊富ですが準備までに時間がかかるので今回は対象外としました。
  • HeartCore CMS : 国内CMSシェアNo.1らしいです。無料プランが無かったので、今回は対象外としました。

Astro との通信検証

今回は、Astro で記事リストを作る通信方法を検証してみます。
検証に関して、以下のページを参考にしています。

https://zenn.dev/oxid/articles/8f324a75af6ccf

https://docs.astro.build/ja/guides/cms/contentful/

Spearly CMS

Spearly はコンテンツを API クライアント経由で取得します。await spearlyApiClient.getList("blog") を実行することで、コンテンツのリストを取得できます。

あとは、表示コンテンツに合わせてフォーマットし直すことでリスト表示できるようになります。

index.astro
---
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>

ボイラープレートは以下のレポジトリにあるのでご自由にお使いください。
https://github.com/mantaroh/spearly-astro-boilerplate/

microCMS

Spearly と同じく、コンテンツを API クライアント経由で取得します。await microcmsApiClient.getList({endpoint: 'blogs'}) を実行することで、コンテンツのリストを取得できます。

あとは、表示コンテンツに合わせてフォーマットし直すことでリスト表示できるようになります。

index.astro
---
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 同様以下のレポジトリにボイラープレートを用意しているのでお使いください。

https://github.com/mantaroh/microcms-blog-template

Newt

Newet も他の CMS 同様ですが、WordPressのスラッグ、Spearly/microCMS のようなエイリアス・Id という別名の概念が無いため、デフォルトの識別子である _id を利用しています。

index.astro
---
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同様にボイラープレートを用意しています。
https://github.com/mantaroh/newt-blog-template

まとめ

実装してみて分かったこととしては以下のような事です。

  • どの CMS も接続方法には差が無さそう
  • Newt はスラッグが見当たらなくページアドレスが自動生成されたもので分かりにくくなるかもしれない
  • Spearly の SDK JS が優秀

Astro を使ってヘッドレス CMS のブログ運用を行うのであれば、構築にさほど時間はかからないのではないかというのが感想です。Newt だけがスラッグが無いので分かりやすいアドレスの運用が難しいかもしれません。

ぜひ、みなさんも Astro + Spearly などを使ったブログの運用を試してみてください!

Discussion