定義
同じメタデータ(タイトル・説明・日付・タグなど記事に関する情報)を検索エンジン用・共有用の複数の産出物にそれぞれ書いていくと、値が互いに食い違いがちだが、それを防ぎたいときに使う原則だ。核心は、その情報を**ちょうど一箇所(単一ソース)**にだけ置くこと。
原則:メタデータを一つの権威ある出所(例:コンテンツファイル上部の frontmatter — ファイルの一番上の --- の間に書くメタ情報のブロック)にだけ置き、そこから派生する産出物はビルド時にその出所から自動生成する。派生産出物とは、sitemap(検索エンジンにページ一覧を知らせる XML)、RSS(購読用の記事一覧フィード)、OG(SNS でリンクをカードとして表示する際に使う og:title・og:image のようなメタタグ)、JSON-LD(Google が理解する構造化データ)のようなものだ。こうすれば、一つだけ直しても残りが常に同じ値で作り直される(「決定的」に生成 — 同じ入力なら常に同じ出力)。
なぜ必要か
同じメタを複数箇所(ランタイム DB、別の設定、ハードコード)に重複保存すると、時間とともに値が食い違う drift が生じ、何が真実か曖昧になる。単一ソースを置けば一貫性が構造的に保証され、派生物は再生成可能な決定的関数の結果になる。静的生成(SSG)環境では、ランタイム DB なしでもビルド時にコンテンツをスキャンしてメタを確定できる。
動作原理
- コンテンツファイルの frontmatter を単一の出所とし、スキーマで検証する。
- ビルド時に
content/をスキャン → パーサー(gray-matter など)→ スキーマ(Zod など)で正規化する。 - 正規化されたメタから、ビルド時の関数がページメタデータ・sitemap・robots・RSS・JSON-LD を生成する。
- AI のような補助生成は、空の description など空欄の推薦にだけ使い、確定値はソースに書いて再び決定的に吸収する。
実務適用
ディレクトリ構造と frontmatter を一致させる不変式(例:ディレクトリの category === frontmatter の category)を置けば、分類の drift もビルドで遮断できる。
トレードオフ
単一ソースは一貫性・再現性が高いが、動的に頻繁に変わるメタ(リアルタイムのカウントなど)にはビルド時の決定が合わない。ランタイム DB は動的性に強いが、SSOT を壊すと drift・非決定性を抱え込む。静的コンテンツのメタには SSOT が、真に動的なデータにはランタイムソースが適する。
使ってはいけない場合
閲覧数・在庫・リアルタイム価格のように本質的にランタイムで変わる値は、ビルド時の単一ソースに入れない。こうした値は別のランタイムソースを置き、静的メタと分離する。
よくある間違い
- 同じメタを frontmatter とランタイム DB の両方に置き、どちらが真実か合意しない。
- AI 自動生成値を検収なしでソースに昇格させ、単一ソースを汚染する。
- スキーマ検証をビルドパイプラインに接続せず、必須フィールドの欠落がランタイムまで流れる。
関連概念
- serverless-stateless-execution — ランタイム常駐 DB を避け、ビルド産出物で決定する選択と接する。