Notionブログをヘッドレス化する際の設計メモ
Notionブログをヘッドレス化させてみようということで、AIと対話しながら色々とまとめてみた。以下、AIにまとめてもらった内容
問題点の整理
Notionでブログを書くのはとにかく楽で、最初はそのまま公開すれば十分だと思っていた。実際、エディタも気持ちいいし、構造も柔軟で、「とりあえず書いて出す」だけならこれ以上ないぐらい快適。ただ、少し運用のことを考え始めると、いくつか気になる点が出てくる。
- URLがページIDベースになり、意味のある構造にならない
- ページの入れ子構造がそのままサイト構造になる
- SEO的な制御(リダイレクト・canonicalなど)ができない
- 画像のURLが安定せず、長期運用に向かない
どれも単体なら許容できるけど、「メディアとして育てる」と考えた瞬間に無視できなくなる。
概要設計
そこで一度前提を切り分けた。
Notionは「書く場所」、公開は「別でやる」。
構成としては以下。
Notion(非公開)
↓ API取得
Astroなどでビルド
↓
静的サイトとして公開いわゆるヘッドレス構成。この形にすると、URL設計とデザインの主導権がすべてフロント側に移る。例えば、
/
├ /blog/
├ /create/のように、最初から意図した構造で設計できる。
ここで躓いたポイント
一番最初に引っかかったのは「公開の概念」。Notionは自動保存なので、「書いたらそのまま反映される」という感覚がある。その延長で公開も同じだと思っていたが、ヘッドレスではそうならない。流れとしてはこうなる。
- 記事を書く
- 公開状態にする
- サイトを再生成する
この「再生成」が必要になる。つまり、公開は操作ではなく結果になる。
次に気になったのが非公開の挙動。記事を published から draft に戻した場合、
- 次のデプロイ時にページが生成されなくなる
- URLは404になる
という動きになる。直感とは少し違うが、仕組みとしてはシンプル。
もう一つ検討したのが、Notionとヘッドレスの両方で公開するパターン。これは一見便利そうに見えるが、
- Notion側でcanonicalが設定できない
- リダイレクトも制御できない
ため、結果的に「どちらが正なのか分からない状態」になる。この時点で現実的ではないと判断した。
最後に一番引っかかったのが画像。Notionに貼った画像は内部的には外部ストレージに置かれているが、
- URLが署名付きで不安定
- キャッシュ戦略が取りづらい
- OGP用途で扱いにくい
といった問題がある。見た目では問題なくても、裏側の挙動が少し不安定。
解決策
ここまでの整理を踏まえて、設計を固めた。
まず公開制御は、Notion側に status を持たせて管理する。
- draft
- published
ビルド時に published のものだけを対象にする。
デプロイはDeploy Hookを使う。URLを叩くだけでビルドが走る仕組みなので、これをそのまま「公開ボタン」として扱う。
ただしそのままだと操作が少し面倒なので、Raycastのコマンドとして登録しておく。
例えば、
- Deploy Blog
- Deploy Create
のように分けておくと、複数メディアでも安全に運用できる。さらに、実行時に確認を入れることで誤操作も防げる。
画像については、NotionのURLをそのまま使わず、ビルド時に取得して外部ストレージ(R2など)に保存し直す。流れとしてはこうなる。
Notion画像URL取得
↓
ダウンロード
↓
R2へアップロード
↓
URLを置き換えこれで画像のURLが安定し、キャッシュも効くようになる。執筆体験はそのままに、公開側だけ安全にするイメージ。
いくつかのパターン
ここまでやる中で、構成としてはいくつかの選択肢があった。
- Notionそのまま公開
→ 最も手軽だが、構造と制御に制限がある - Notionとヘッドレスの併用
→ 一見便利だが、重複コンテンツになりやすく制御が難しい - ヘッドレス一本化
→ 設計が整理され、長期運用に向く
最終的な整理
今回整理して一番しっくりきたのは、「役割を分ける」という考え方だった。Notionはあくまで、記事を書く場所であり、状態を管理する場所。公開は、その状態を元に生成された結果として扱う。
この構成にすると、公開という行為自体の捉え方が少し変わる。ボタンを押して出すものではなく、状態を整えた上で「出てくるもの」になる。最初は少し回りくどく感じるけど、一度この形にしてしまうと、むしろすべてが整理される。
URLも、構造も、公開のタイミングも、どこで何を制御しているのかがはっきりする。
Notionの書きやすさはそのままに、ちゃんと自分のサイトとして扱える状態になる。いったんこの構成で運用してみる。