これはヘッドレスCMSとは呼ばないのでは…
はじめに
こんにちは。農工大で1年生をやっております。
2,3ヶ月前から、当サークルのホームページを一から作り直すプロジェクトを始めており、なんと、プロジェクトメンバーは僕1人(泣)
今回は、ヘッドレスCMSを使いたいけど使えない事情と、その解決策(?)について書きました。
前提
- Next.js13でSSGして使う。(バックエンドなし)
- GitHub Actionsでデプロイする。
ヘッドレスCMSとは
最近のフロントエンドでは非常に良く使われています。すでに様々なサービスが存在しており、
- コンテンツの保存・管理
- コンテンツ取得用のAPIの提供(Rest, GraphQL)
- エディタ(マークダウン, リッチテキスト)
- GitHub Actionsのトリガー(デプロイ)
- チーム管理(権限など)
などが機能としてあります。
ヘッドレスCMSがどのようなものか、詳しくは以下のサイトなどをご覧ください。
https://blog.microcms.io/what-is-headlesscms/
ヘッドレスCMS導入への壁
僕が求める要件はこんな感じ
- 本体リポジトリにコミットせずに、記事を更新したい
- 記事を更新する人の手間を増やさない(新規アカウント登録など)
- サーバーなしで運用したい
- できれば新しいサービスを利用せずに済ませたい
- 無料
部所有のサーバーがない、旧サイトを誰も更新しなかった、僕が下っ端なので部のアカウントを管理できない、などが理由です。
最有力候補だったStrapi
というヘッドレスCMSでさえ多くの要件を満たせません。
おっ!
ここで注目! Githubは、ブラウザからプレビュー付き簡易エディタを使えます。
まず、マークダウン置き場のリポジトリを新規作成します。こちらでは、メインブランチのみ使用し、を 「保存 = メインに直コミット」 とします。
これにより、
- 部員なら誰でも、
- ローカル・ブラウザ・モバイルアプリのどの環境からでも編集できて、
- git関連の面倒な手順なく、
- 本体のシステムを更新せずに、
CMSとして使える!!
画像もアップロードできるので、画像だけはpublic/
ディレクトリに置かなければならないと言う不便な点も解消されます!!
どうやってデータ取得するのさ
普通、ヘッドレスCMSでブログといえば、RestやGraphQLなどのAPIをビルド時にたたき、データを取得します。
GitHubのリポジトリからデータ取得するAPIなんてあるのか?と思うかもしれませんが、簡単です。
「ビルド時にリポジトリをクローン」
すればいいんです!
実装について
まず、リポジトリをcontent
ディレクトリにクローンする下記ファイルを作成します。
次に、package.json
を編集します。
npm-scripts
の機能で、npm run build
でbuild
の実行をすると、先にprebuild
が実行されます。これで、ビルド直前にデータを取得できますね。
マークダウン変換処理
メタデータの抽出にgray-matter
、変換処理にunified
とそのプラグインを使います。
- ビルド時に、マークダウンからタイトルや日付等のメタデータを抽出した後、HTMLに変換
- クライアント側で表示する際、HTMLからReact Componentに変換
長くなるので、ここでは詳しく解説しません。
こちらの記事が非常に参考になりました。
https://www.haxibami.net/blog/posts/blog-renewal
また、Vercelが様々なテンプレートを用意しているので、それらのソースコードを見てみるのも参考になると思います。
その他小細工
ブラウザエディタからコピペで画像をアップロードする際は、自動的にURLを割り当ててくれるので問題ないのですが、画像ファイルを単体でアップロードし、相対パスで表示したい時もあります。
例えば、webp画像はブラウザエディタでサポートされていませんし、ローカルからはそもそも自動でURLを割り当てられません。
そこで、裏技的に、GitHubのraw
表示を使います。
実は、https://raw.githubusercontent.com/organization-name/リポジトリ名/ブランチ名/該当ファイルのパス
とすることで、画像を取得できます。
utils/
ディレクトリなどにパース用関数を用意し、先ほどのHTMLからReact Componentに変換する際や、メタデータに含まれるサムネ画像URLなどを取得する際に、パース処理を挟めば完璧です!
まとめ手順
- CMS用リポジトリにてマークダウンファイルを追加・編集
main
にコミットすることで保存- 本体リポジトリにて、手動でデプロイ用のGitHub Actions workflowを実行
- ホームページが更新
おわりに
2つの別リポジトリが密結合な状態にあるのがちょっと気になりますが、今後新しくホームページを作り直すことになっても使いまわせそうなので、やっぱりこれで正解だったと思います。
今後は、もっとワンポチくらいでデプロイできる仕組みを考えたいですね。サークルのDiscordサーバーにそれ用のbotを作って入れるとか…?
最後に、ソースコードを貼っておきます。