定義
検索エンジンや回答エンジンに、自分のページの FAQ・価格・製品説明を引用させたいとき、機械向けマークアップ(構造化データ) に入れる内容は、人間が HTML 上で実際に読める内容と一致していなければならない。
構造化データ(structured data) は、schema.org の語彙でページの意味を記述した JSON-LD などである。可視コンテンツ(visible content) は、ブラウザにレンダリングされ、ユーザー(またはクローラーが DOM/テキストとして)閲覧できる本文・見出し・FAQ である。両者の 一致(parity) とは、マークアップの各主張(質問・回答・価格)が、画面上に対応するテキストとして存在することを意味する。画面にない Q&A だけを FAQPage として入れるのは、この概念の逆である。
なぜ必要か
構造化データがなければ、機械は価格や FAQ の関係を不安定に推測する。逆に、マークアップだけが豊富で画面が薄い(thin content)場合、検索ポリシー上は隠しマークアップやスパムに近い扱いとなり、ユーザーは引用された回答をページ上で見つけられない。ログイン壁やプレビュー制限 UI を使う場合でも、オーバーレイに実際の H1・説明文・FAQ を載せて可視テキストを確保し、そのテキストと JSON-LD を 同じデータソース から生成する必要がある。
動作原理
- FAQ・プラン・製品説明を
faqContent.tsのような 配列/モジュール一つ に置く。 - UI コンポーネントはその配列を map してアコーディオンや一覧を描画する。
- JSON-LD ビルダーは同じ配列から
FAQPage/Offerノードを生成する。 - 条件付きレンダリング(匿名ユーザーのみ FAQ 表示など)と graph への含め方を 同じ条件 で束ねる — 画面から FAQ を外したら FAQPage ノードも外す。
- デプロイ前に HTML ソースで
application/ld+jsonの文字列と本文テキストを照合する。
実務での適用
- 公開ホーム・ランディング: ロック/ブラー UI でも、オーバーレイに H1・短い説明・FAQ を置く。
- 価格ページ:
Offerはハードコードされた数値より 実際の料金表関数 から導出し、UI とのドリフトを防ぐ。 - i18n: ロケール別 FAQ 配列を使い、各ロケールページの JSON-LD もそのロケールの配列を使う。
- 別
/landingで権威を分散させるより、可能なら canonical なホームにコンテンツを置く 方向を検討する。
トレードオフ
| 選択 | 利点 | コスト |
|---|---|---|
| SSOT 配列 | 不一致バグの減少 | モジュール設計・型共有が必要 |
| マークアップのみ豊富 | 短期 rich result の誘惑 | ポリシーリスク・ユーザー不信 |
| 別ランディング URL | 実験の自由度 | 検索権威・canonical の分散 |
使うべきでない場合
- 画面に一切表示しない内部 FAQ を JSON-LD だけに入れる場合。
- CSS
display:none/ 0px フォントで「可視」を偽装する場合。 - ログイン後にのみ見える回答を匿名ページの FAQPage に入れる場合(条件不一致)。
よくある失敗
- UI で FAQ をリファクタで削除したのに JSON-LD はそのまま残す。
grep hreflangが 0 件だからバグと誤診 — React がhrefLangで出力する大文字小文字の問題と混同(別問題だが、ソースの大文字小文字を無視して検索 して確認する)。- モック E2E だけを信じて、本番環境の thin content や 401 リダイレクトを見逃す。
関連概念
- json-ld-structured-data — サーバーから JSON-LD script を注入するパターン
- single-source-of-truth-content-metadata — メタ・本文の単一ソース
- auth-resolution-gated-data-fetching — 公開ホームが 401 で弾かれないようにするゲート