2026年5月30日
2026年5月30日
WordPressの記事にFAQスキーマ(FAQPage構造化データ)を追加する方法|プラグインとコードの両方を解説
WordPressの記事にFAQスキーマを追加するには、SEOプラグインのFAQブロックを使う方法と、wp_head にJSON-LDを自分で出力する方法の2通りがあります。どちらの場合も「ページに見えているQ&Aと同じ内容をマークアップする」ことが前提です。この記事では、両方の手順と、テストツールでの確認方法、Googleの表示条件の変化を踏まえた現実的な期待値までを解説します。
FAQスキーマとは何か、今入れる意味はあるか
FAQスキーマは、schema.org の FAQPage 型を使って「このページには質問と回答の一覧がある」と検索エンジンに伝える構造化データです。中身は Question(質問)と、その acceptedAnswer(回答)の組を並べたもので、HTMLとは別にJSON-LD形式で書くのが一般的です。
以前は、FAQスキーマを入れると検索結果に質問の折りたたみ表示(FAQリッチリザルト)が出ることがあり、多くのサイトが導入しました。しかしGoogleは2023年8月に、FAQリッチリザルトの表示対象を、政府系や医療系などの信頼性の高い一部のサイトに限定すると発表しています。一般的なブログや企業サイトでは、マークアップを入れても検索結果の見た目は変わらないと考えておくのが妥当です。
それでも導入する理由はあります。
- 検索エンジンがページの構成(どこが質問でどこが回答か)を機械的に読み取りやすくなる
- Google以外の検索エンジンや、構造化データを参照するサービスでは使われる可能性がある
- 記事内にQ&Aを整理して置くこと自体が、読者にとって読みやすい構成になる
逆に「リッチリザルトでクリック率を上げる」ことだけが目的なら、手間に見合わない可能性があります。Googleの扱いは変わることがあるため、導入前に Google 検索セントラルの「FAQ(FAQPage)の構造化データ」のページで最新の条件を確認してください(2026年10月現在の状況も、公式ドキュメントでの確認を前提にしています)。
導入前に守るべきルール
FAQスキーマはどのページにも付けてよいものではありません。Googleのガイドラインで特に重要なのは次の点です。
- ページ上に表示されている内容と一致させる:JSON-LDにだけ書かれていて画面に出ていないQ&Aは対象外です。隠しテキスト扱いになるおそれがあります。
- サイト運営者が用意した質問と回答であること:ユーザーが自由に投稿して複数の回答がつく形式(Q&A掲示板など)は
FAQPageではなくQAPageの対象です。 - 広告目的に使わない:回答の中身が商品の宣伝だけ、というような使い方はガイドライン違反になり得ます。
- 同じFAQを複数ページに貼る場合は1か所だけにマークアップする:全記事の末尾に共通のFAQを出しているなら、マークアップはそのFAQのメインページだけにします。
また、1ページに FAQPage を二重に出力しないことも大切です。プラグインのFAQブロックと自作コードを併用すると重複しやすいので、どちらか一方に決めてください。
方法1:SEOプラグインのFAQブロックを使う
すでに Yoast SEO や Rank Math を使っているなら、プラグインが用意しているFAQブロックを使うのがいちばん手軽です。
Yoast SEO の場合
Yoast SEO には、ブロックエディターで使える「Yoast FAQ」ブロックがあります。投稿の編集画面でブロック追加ボタンを押し、「FAQ」で検索すると見つかります。ブロックを挿入したら、質問と回答を入力欄に書いていくだけで、Yoast SEO が出力する構造化データのまとまり(schema graph)に FAQPage が組み込まれます。
Rank Math の場合
Rank Math にも「FAQ by Rank Math」ブロックがあります。使い方は同様で、質問と回答を入力すると構造化データが出力されます。設定画面の構成やブロック名はプラグインの版によって変わることがあるので、見つからない場合はプラグインの公式ドキュメントを確認してください。
プラグイン方式のつまずきどころは、ブロックを使わずに普通の見出しと段落でQ&Aを書いても構造化データにはならないことです。既存記事のQ&Aを対象にしたいなら、その部分をFAQブロックに置き換える必要があります。
方法2:コードでJSON-LDを出力する
SEOプラグインを使っていない場合や、出力内容を自分で管理したい場合はコードで出力します。ここでは、WordPress標準の「詳細」ブロック(core/details、開閉できるブロック)でFAQを書き、そのブロックから自動でJSON-LDを組み立てる方法を紹介します。画面に出ている内容とマークアップが常に一致するので、ガイドラインの「表示内容と一致させる」を守りやすいのが利点です。
記事側の準備
- 記事内のFAQにしたい箇所に「詳細」ブロックを追加します。
- 見出し部分(summary)に質問を、中身に回答を書きます。
- ブロックの設定サイドバーの「高度な設定」にある「追加CSSクラス」に
is-faqと入力します。
クラスで目印をつけるのは、記事内の「詳細」ブロックをすべてFAQ扱いにしないためです。補足説明やコードの折りたたみにも使われるブロックなので、FAQとして出したいものだけを選べるようにしておきます。
functions.php に追加するコード
子テーマの functions.php、または自作プラグインに次のコードを追加します。編集前にファイルのバックアップを取り、FTPやファイルマネージャーで元に戻せる状態にしておいてください。
<?php
/**
* 「詳細」ブロック(クラス is-faq)から FAQPage の JSON-LD を出力する
*/
function mysite_collect_faq_items( array $blocks, array &$items ) {
foreach ( $blocks as $block ) {
if ( 'core/details' === $block['blockName'] ) {
$class = isset( $block['attrs']['className'] ) ? $block['attrs']['className'] : '';
if ( preg_match( '/(^|\s)is-faq(\s|$)/', $class )
&& preg_match( '#<summary[^>]*>(.*?)</summary>#s', $block['innerHTML'], $m ) ) {
$answer_html = '';
foreach ( $block['innerBlocks'] as $inner ) {
$answer_html .= render_block( $inner );
}
$question = trim( html_entity_decode( wp_strip_all_tags( $m[1] ), ENT_QUOTES | ENT_HTML5, 'UTF-8' ) );
$answer = trim( html_entity_decode( wp_strip_all_tags( $answer_html ), ENT_QUOTES | ENT_HTML5, 'UTF-8' ) );
if ( '' !== $question && '' !== $answer ) {
$items[] = array(
'@type' => 'Question',
'name' => $question,
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => $answer,
),
);
}
}
}
if ( ! empty( $block['innerBlocks'] ) ) {
mysite_collect_faq_items( $block['innerBlocks'], $items );
}
}
}
function mysite_output_faq_schema() {
if ( ! is_singular() ) {
return;
}
$post = get_queried_object();
if ( ! ( $post instanceof WP_Post ) || ! has_block( 'core/details', $post ) ) {
return;
}
$items = array();
mysite_collect_faq_items( parse_blocks( $post->post_content ), $items );
if ( empty( $items ) ) {
return;
}
$data = array(
'@context' => 'https://schema.org',
'@type' => 'FAQPage',
'mainEntity' => $items,
);
echo "<script type=\"application/ld+json\">"
. wp_json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP )
. "</script>\n";
}
add_action( 'wp_head', 'mysite_output_faq_schema' );
コードのポイント
parse_blocks()で本文をブロック単位に分解し、グループブロックなどの中に入れ子になった「詳細」ブロックも再帰でたどっています。- 質問文は「詳細」ブロックのHTMLにある
<summary>要素から取り出し、回答は中のブロックをrender_block()で描画してからタグを取り除いています。回答をプレーンテキストにしているのは、構造化データの中にリンクや装飾が残って崩れるのを避けるためです。 wp_json_encode()にJSON_HEX_TAGを指定しているのは、本文中に<や>が含まれていても</script>で出力が途切れないようにするためです。日本語をそのまま読めるようJSON_UNESCAPED_UNICODEも付けています。- 投稿者が書いた内容をそのまま出しているので、出力前のエスケープに相当する処理(タグ除去とJSONエンコード)を省かないでください。
テーマによってはクラシックエディターで書かれた古い記事もあると思います。その場合は「詳細」ブロックが存在しないので、このコードは何も出力しません。古い記事に入れたいときは、Q&A部分をブロックに変換してから is-faq を付けます。
正しく出力されているか確認する
追加したら、記事を公開(または更新)してから次の順で確認します。
- ページのソースを確認する:ブラウザでページのソースを表示し、
FAQPageで検索します。<script type="application/ld+json">の中に質問と回答が入っていれば出力はできています。2件以上見つかる場合は、プラグインとコードが二重に出力しています。 - リッチリザルトテストにかける:Googleの「リッチリザルト テスト」に記事のURLを入力します。FAQとして認識されれば検出項目にFAQが表示されます。ただし前述のとおり、テストで有効と出ても実際の検索結果に表示されるとは限りません。
- Schema Markup Validator で文法を確認する:schema.org が提供する検証ツールでは、Googleの表示対象かどうかに関係なく、構造化データとして文法が正しいかを確認できます。
キャッシュ系プラグインやCDNを使っている場合、変更直後は古いHTMLが返ってきてJSON-LDが見えないことがあります。確認前にページキャッシュを削除してください。
よくあるつまずき
- テストで「FAQ」が検出されない:質問または回答が空のまま保存されている、
is-faqのクラス名が違う(全角や余分な文字)、などが典型です。ソースにFAQPage自体が無いのか、あるのに認識されないのかで切り分けます。 - 構造化データが二重に出る:SEOプラグインの設定で構造化データ出力を有効にしたまま、自作コードも動かしているケースです。どちらかを止めます。
- 回答の文章が途中で切れる:回答の中に表や埋め込みなど、テキストにすると意味をなさないブロックを入れていないか確認します。回答は短い文章でまとめるほうが扱いやすくなります。
- 検索結果に表示されない:多くのサイトでは仕様どおりの挙動です。マークアップの誤りを疑う前に、Googleの表示対象の条件を確認してください。
まとめ
- FAQスキーマは
FAQPage型の構造化データで、ページに表示されているQ&Aと同じ内容をJSON-LDで記述します。 - Googleは2023年8月以降、FAQリッチリザルトを一部の信頼性の高いサイトに限定しているため、一般サイトでは検索結果の見た目の変化は期待しすぎないほうが無難です。
- 手軽に入れるなら Yoast SEO や Rank Math のFAQブロック、自分で管理したいなら「詳細」ブロックから JSON-LD を組み立てるコードが使えます。
- どちらの方法でも、二重出力を避け、ソース・リッチリザルトテスト・Schema Markup Validator の3段階で確認します。