本文へ

開発記録

公開コンテンツを Astro Content Collections とローカル Markdown から始める理由

現在のコンテンツ量、データモデル、公開の境界から、CMS をすぐに導入せず、Astro Content Collections とローカル Markdown を先に使う理由を説明します。

林予晴
公開
  • Astro
  • Content Collections
  • Markdown
  • コンテンツ設計

コンテンツサイトに最初から CMS を導入すると、仕組みがひと通り整ったように感じられます。ただ、このサイトで先に解決したいのは、記事の識別、言語別バージョン、下書きと公開の境界、そして正式な出力です。リモートの管理画面を用意することではありません。

今、Astro Content Collections とローカル Markdown を選んでいるのは、CMS が悪いからでも、この構成を長期的に使い続けると決めたからでもありません。判断の軸は、現時点の公開ノートの量と共同作業の進め方では、編集画面のためだけにデータベース、ログイン、権限管理、別の公開システムを導入する必要はまだない、ということです。まずコンテンツの契約を固めるほうが、コストを抑えられ、検証もしやすくなります。

コンテンツに本当に必要なものから考えます

現在のノートはサイトの一部であり、リアルタイムの取引を扱うデータサービスではありません。記事に必要なのは、次のような仕組みです。

  • 同じ記事の言語別バージョンを対応づけられる、安定した識別子。
  • 言語ごとに独自の URL を持つための slug と locale。
  • コンテンツの状態と日付を分けて表す draft、publishedAt、updatedAt。
  • category、tags、タイトル、概要、著者などのメタデータ。
  • ビルド時に HTML を生成する公開ページと、ローカルで確認できる下書きプレビュー。

これらはすべて、Markdown の frontmatter と Content Collection の schema で表現できます。この段階で CMS を導入して解決できるのは、リモートでの編集と管理です。記事をどう識別するか、言語別バージョンをどう対応づけるか、どのコンテンツを公開してよいかまで、自動で決めてくれるわけではありません。

Content Collections が提供するのはコンテンツの契約です

ローカル Markdown だからといって、データを自由に書いてよいわけではありません。Astro の collection loader が src/content/notes/ 以下の記事を読み込み、schema が各ファイルの frontmatter を検証します。

現在のデータの流れを簡略化すると、次のようになります。

ローカル Markdown
  → Content Collection loader
  → noteSchema
  → getAllNotes()
  → getPublishedNotes()
  → ホーム、一覧、記事ページ、sitemap

schema は locale、slug、日付形式、現在対応している category を制限し、下書きではない記事に publishedAt がない状態も拒否します。記事の取得処理では別途、同じ言語内で slug と stableId が重複していないかを確認し、ファイルが置かれた言語ディレクトリと locale が一致していることも検証します。

これらの確認によって、Markdown の読みやすさを保ちながら、記事の構造を著者の推測に任せずに済みます。ファイルがコンテンツの取得元、schema がコンテンツの境界、公開対象を取得する処理が公開可否の境界を担います。

今はリポジトリに置く理由

コンテンツとそのバージョンを一緒に確認できます

記事は、サイトのレイアウト、ルート、検証スクリプトと同じプロジェクトに置いています。ある記事にそのフィールドがある理由や、どのページが使うのかを調べるときは、コンテンツモデルと利用箇所からたどれます。別のシステムにログインして、リモートのデータと照合する必要はありません。

記事の変更とコードの変更を分けて確認することもできます。記事の追加なら Markdown とコンテンツの検証だけを確認でき、公開ルールの変更ならページと sitemap も併せて確認します。それぞれの変更に対する責任は異なりますが、データの取得元が別の見えない管理画面に隠れることはありません。

公開ページは実行時の問い合わせを必要としません

現在のサイトは静的出力です。正式なビルドで記事を読み込み、ホーム、一覧、記事詳細ページ、sitemap を生成します。ブラウザーが受け取るのは生成済みの HTML なので、読者がページを開くたびにコンテンツ API に問い合わせる必要はありません。

この方法だから静的出力のほうが必ず速い、あるいは検索結果が必ずよくなる、とは言えません。確認できるのは、記事の公開可否とページの出力を同じビルド処理で決定でき、実行時のコンテンツサービスを一つ管理せずに済むことです。

下書きと公開の境界を直接表現できます

ローカルプレビューでは有効な Markdown をすべて読み込めますが、公開ページが読むのは公開可能な記事だけです。下書きがファイルとして存在しても、自動的に正式なルートになるわけではありません。draft、publishedAt、公開日の条件を満たした記事だけが公開対象の集合に入ります。

そのため、コンテンツの校正を先に進めながら、正式なサイトには確認済みの記事だけを載せておけます。この境界は CMS でも実現できますが、現時点のデータ量であれば、ファイル、schema、取得関数で十分に表現できます。

この選択で意図的に範囲外にしていること

ローカル Markdown にも明確な負担があります。現在、次の機能は提供していません。

  • ブラウザー内の記事エディター。
  • 技術職ではない編集者がログインして直接変更できる管理画面。
  • 再ビルドせず、すぐに更新できるリモート公開フロー。
  • 組み込みのアカウント、権限、コメント、購読管理。
  • コンテンツシステムが自動で提供する全文検索、レビューのワークフロー、バージョン比較画面。

これらは隠された機能ではなく、現在の範囲に含めていない機能です。執筆、校正、公開をリポジトリとローカルプレビューで進められる限り、こうしたシステムの複雑さを今は引き受けない、という意識的なトレードオフです。

公開ノートとプロダクトのデータも分けて考える必要があります。記事にはビルド時に扱うコンテンツが向いています。一方、アカウント、財務データ、ユーザーの操作後すぐに保存する必要があるデータまで、サイトが Markdown を使っているという理由で Markdown に詰め込むべきではありません。

CMS を再検討する条件

今後、次のような必要性が出てきたら、CMS や別のコンテンツサービスを再検討できます。

  • リポジトリを直接変更しない著者や編集者が複数いる場合。
  • 開発者ではない人が、頻繁に記事を即時公開する必要がある場合。
  • コンテンツのレビュー、権限管理、予約公開、バージョン比較が日常的な作業になる場合。
  • 記事数や問い合わせの要件が増え、ローカルファイルでは管理しづらくなる場合。
  • サイト以外のプロダクト、アプリ、API でも同じコンテンツを共有する必要がある場合。

こうした条件がそろえば、CMS が実際の作業を減らす可能性があります。ただし、導入後も stable ID、言語別バージョン、公開条件、キャッシュ、プレビュー、出力検証を設計し直す必要があります。管理画面に切り替えてもコンテンツの契約はなくなりません。取得元がファイルから別のシステムに移るだけです。

逆に、モックアップに記事一覧が描かれていることや、将来記事が増えるかもしれないことだけでは、今 CMS が必要だという根拠にはなりません。画面上の配置が示すのは読者の読み進め方であり、管理システムの必要性を裏づけるものではありません。

この構成で現在確認できること

現在の loader、schema、取得関数、ページルート、出力検証から、次のことを確認できます。

  • Markdown の記事を、管理されたメタデータとともに Content Collection に取り込めます。
  • 正式なページは公開対象の集合を使い、すべてのファイルをそのまま公開コンテンツとして扱いません。
  • 言語別の記事は stableId で対応づけられ、URL は引き続き各言語の slug で決まります。
  • 下書きは Astro dev でプレビューでき、正式な build ではプレビュールートを登録しません。
  • ホーム、一覧、記事ページ、sitemap で同じ公開条件を使えます。

一方、これらの証拠から、次のようには結論づけられません。

  • どのチームにとっても、ローカル Markdown が CMS より優れていること。
  • 今後もコンテンツの量が増えず、管理画面が必要にならないこと。
  • 読者が必ずファイルベースのコンテンツ運用を好むこと。
  • 静的出力によって、パフォーマンス、SEO、アクセス数、事業上の成果がすでに証明されたこと。

今の選択が答えているのは、より限定された問いです。このコンテンツ量、この共同作業の進め方、この静的公開の境界では、どの取得元を使うと、まず正しく実装し、検証しやすいかを考えています。

取得元を小さく保っても、将来の選択肢は閉じません

記事の識別、言語別バージョン、公開条件を特定のページに埋め込んでいなければ、将来取得元を変更しても、同じ公開契約を維持できます。先に決めるべきなのは、何を同じ記事とみなすか、どのバージョンを公開できるか、ページがどこから内容を読み込むか、そして出力をどう検証するかです。

今、Astro Content Collections とローカル Markdown を使うのは、これらの契約で十分であり、CMS の追加機能を必要とする根拠がまだない段階で、システムの範囲を小さく保つためです。コンテンツの作業が本当に別のツールを必要としたら、新しい要件に照らして再検討します。想像上の規模のために、先回りして保守コストを負担する必要はありません。

この記録の範囲

この記事は、現在の Content Collection loader、note schema、記事の取得処理、プレビュー integration、ページルート、sitemap、スタジオの開発仕様に基づいてまとめています。今は CMS を先に導入しない理由と、その判断に伴う制約を説明するものです。他のコンテンツチームに CMS が適さないとは主張していません。また、将来の管理画面、検索、リモート公開を、すでに存在する機能として扱ってもいません。

開発記録コンテンツ設計

記事の目次は本文のレンダリング後の見出しから作る

このサイトの記事レイアウトを例に、レンダリング後の見出しから目次を作り、見出しの文字列・順序・アンカーの参照元を共通化する方法と、モバイルの Drawer、JavaScript なしでの閲覧、現在の節の表示を分けて扱う理由を説明します。

ノートを読む