Astro + Contentful でオレオレブログを作ってみた

2023/10/25

Astro + Contentful でオレオレブログを作ってみました。わりと大変だったので酔狂な人以外ははてなブログとかにした方がいいです。 でも結構作るのは楽しいので作るのが好きな人にはオススメ!

Astro + Contentful でブログ作ってみた

Astro と Contentful(と Tailwind CSS, daisyUI, 一部 React) でブログを作ってみました。
デプロイ先は Cloudflare Pages の予定です。

repo: https://github.com/SeeLog/blog

ダラダラ作っていたら1ヶ月位かかっちゃった。

技術的な詳細とかはまた追って記事にするかもしれないし記事にしないかもしれません。
細かなこだわりとか、悲しいトラップとかを色々経験できたので・・・

動機

Q. 一言で動機をどうぞ

A. なんとなく

真面目なところだと以下の動機があります。

  • CMS を使ってみたかった
  • Astro で静的サイトビルドするのが面白そうだった
  • オレオレブログをなんとなく作りたかった

良かったところ

まずはよかったところからツラツラと

Astro

JavaScript を引っ剥がす、そう謳われている通り、ビルド成果物から余分な JS が消える。消えるというより、JS が全然突っ込めない、といったほうが正しいかもしれないですね。
ブログのような方式の Web サイトだと思ったよりも JS を突っ込む必要がないので相性は結構良いと思います。

また 公式ドキュメント に実装例がわりと多めに乗っていたりするのも良いですね。

今となってはフロントエンドだとあって当たり前な機能になりつつありますが、ホットリロードはやはり最高です。
これがあるのとないのとでは開発効率が全く違いますね。これがまともに動くスペックの PC を買うことが重要です。

Contentful

コンテンツのモデルを作ったり、コンテンツそのものを作成したりするのがかなり簡単。
この部分をリポジトリで管理みたいなことをすると多分相当だるいと思います。主に画像とか。
こういう部分がネックでブログを書かなかったら意味ないですからね!

Cloudflare Pages

基本的に無料(制限が実質個人1人だけの開発だとそうそう超えない)、商用利用 OK、Cloudflare でドメインを取っていた場合の連携が楽ちん、と個人開発にとても優しい仕様になっていると思います。

ドメインも卸値直販価格だし、なんでこれ無料なんだ?
とても良い時代になりました。Cloudflare 関連のサービス、今アツくてオススメです。

ただデプロイするときにビルド先の locale になるので toLocaleDateString() とか使っている場合は注意が必要です(1敗)
引数に明示するか、グローバルにしたい場合はアイランドアーキテクチャの検討が必要かも

悪かったところ

お気持ちを書いていく

Astro

Astro は結構辛みも多い

JSが埋め込めない

良かったところと表裏一体ですが、JS が気軽に埋め込めないことです。
特に相性が悪いなと思ったのは ダークモード対応 になります。

ダークモードの対応は

  • ローカルストレージの設定を見る
    • なければ端末の設定を使う
  • 右上のボタンで切り替えたらローカルストレージに設定を書き込む

みたいな仕組みですので、全くもってステートレスではありません。
JSがないと不可能なので Astro とは相性が悪いです。

一方で個人的にダークモードはアクセシビリティ的に重要だと考えているので実装しておきたい気持ちが結構あります。
JS を引っ剥がす思想と反するのはわかるのですが、なんかワンパンで対応できるプラグインとかがあると良いんですけどね〜

以下あたりを参考にして daisyUI のシステムで管理できるように実装してみました。

fetch した Markdown をデフォで描画できない

これ超致命的です。 デフォだと Markdown はローカルに置いたものしか描画できません。
つまり Contentful 等の CMS から fetch してきた Markdown 記法の記事が描画できません。

このあたりは astro-remote というパッケージを使って解決しました。
Tailwind を使っている関係で、これを使うだけだとスタイルが当たらないので astro-remote のドキュメントを見て適切な props を与えてあげる必要があります。

一方でこのカスタマイズ性のおかげで柔軟な Markdown の描画が可能です。
めんどくさい一方で思ったようにカスタマイズしていけるのは結構楽しかった。

VS Code Extension が弱い

React などの Extension と比較すると補完周りが結構怪しいです。
定義済みなのにちゃんと出てこなかったり、逆に定義をちゃんとしていないのに出てきてしまったり(もちろん動かないのでビルドで弾かれる)
あとフォーマッタとかもうまく動いたり動かなかったりで怪しい動きしていますね。

開発中に小さなストレスが溜まっていくのがわかるので本業では正直使いたくないかな・・・

独特の記法に慣れなければいけない

JSX/TSX を知っているだけでは微妙に足りなくて、ちょっと独特の記法に触れないといけません。

以下はこのブログのタグコンポーネントの実装です

Tag.tsx
1---
2type Props = {
3 href?: string
4}
5
6const { href } = Astro.props as Props;
7
8const Container = href ? 'a' : 'div';
9---
10
11<Container class="badge badge-neutral px-3 py-3" href={href}>
12 #<slot />
13</Container>

--- で仕切ってコンポーネントを作ります。
props を型定義、そして Astro.props で型を受け取り、アクセスできるようにする、みたいなところが上部のお仕事です。

下部では JSX の記法でコンポーネントの構造を書いていきます。

これくらいならまだいいのですが、dynamic routing をやりだすと途端に上部の部分で何やってんのかよくわからなくなってきます。
とくに dynamic な部分が複数箇所あったり、その過程でデータフェッチなどが絡んでくると結構厄介です。

このあたりはもっと気軽に、かつ明示的に何を上の世界から下の世界に対して吐き出したいのかをうまく扱えると開発体験が良くなりそうです。

Contentful

型定義が怪しい

データフェッチする際の order(ソート対象とかを指定するやつ) の型定義がうまく行かず無限に時間を溶かしました。
結局怒られ続けて勝利できなかったので泣きながら @ts-ignore を使ってしまいました。

たぶん僕が型定義を間違えている可能性も十分にありそうなのですが、そもそもこの型定義は Contentful と繋いだときに自動生成してくれるのが理想かな、と思います。
もしかしてやる方法あるけど僕が見落としていただけの可能性もありますが・・・

Markdown エディタを全画面にしないとバグる?

再現条件がよくわかってないですが、Markdown エディタを全画面の状態にしないと日本語入力中に別の文章が勝手に突っ込まれたりしてバグることがあります。
これ結構だるいです。

Markdown エディタで改行しても追従してくれない

記事を書いている途中で改行してもエディタが追従してくれません。
いちいち自分でスクロールをしないといけないのでこれも結構だるいです。

Markdown は VS Code で書いてコピペしようかな、と思ったのですが、この場合は画像などを貼るのがめんどくさくなるんですよね〜

一応文字を入力し始めるとスクロールされるんですが、それまではされないので「カーソルどこいった?」ってなります。
まあ慣れの問題なんですかね〜

何書くつもり?

技術系の何かを書いたり、お気持ち書いたりしようかなと思っています。
Zennもあるけど使い分けはどうしようかあまり決めていません。

ぶっちゃけ単純に見てもらうとか、コメントや反応が欲しい、とかであればオレオレブログを作る意味は全く無いですね。やりたかったからやる、作りたかったから作る、個人開発はこうじゃないと!

このブログには現状コメント機能がないので、コメントは GitHub の issue @seeloglog まで直接文句言いに来てください(?)

Any comments are welcome!!

カテゴリー
プログラミング言語
フレームワーク/ライブラリ
ハードウェア
その他技術系
雑記