AIOSEOのFAQスキーマと自作FAQが競合したときの解決方法


背景

WordPressでFAQを実装する際、AIOSEO(All in One SEO) を使っていると自動的にFAQの構造化データ(JSON-LD)が出力されます。
一方で、テーマ側で独自にFAQスキーマを出していると「同じページにFAQスキーマが二重に出力」されるケースがあり、SEO的に好ましくありません。

そこで、AIOSEOのFAQスキーマを停止し、テーマ側で1つだけJSON-LDを出力する方法を紹介します。


解決方法

1. AIOSEOのFAQスキーマを止める

以下をテーマのfunctions.phpに追記します。

// AIOSEOのFAQスキーマを無効化
add_filter('aioseo_faq_schema', '__return_false');
add_filter('aioseo_faq_jsonld', '__return_false');
add_filter('aioseo_faq_structured_data', '__return_false');

これでAIOSEO側の出力は止まります。


2. 自作FAQスキーマを出力する

記事本文からFAQを拾い、JSON-LDとして出力します。
以下をfunctions.phpに追加してください。

// FAQスキーマを出力
function my_faq_jsonld() {
  if (!is_singular('post')) return;

  global $post;
  $content = apply_filters('the_content', $post->post_content);

  $faqs = [];

  // FAQブロック(.faq内のh3を質問、直後の段落を回答とする)
  if (preg_match_all('/<h3[^>]*>(.*?)<\/h3>(.*?)<p>(.*?)<\/p>/is', $content, $matches, PREG_SET_ORDER)) {
    foreach ($matches as $m) {
      $q = trim(strip_tags($m[1]));
      $a = trim(strip_tags($m[3]));
      if ($q && $a) {
        $faqs[] = [
          '@type' => 'Question',
          'name'  => $q,
          'acceptedAnswer' => [
            '@type' => 'Answer',
            'text'  => $a
          ]
        ];
      }
    }
  }

  if (empty($faqs)) return;

  $json = [
    '@context'   => 'https://schema.org',
    '@type'      => 'FAQPage',
    'mainEntity' => $faqs
  ];

  echo '<script type="application/ld+json">' . wp_json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</script>';
}
add_action('wp_head', 'my_faq_jsonld');

3. FAQの記述例

記事本文に以下のように書いておけば、自動的にJSON-LDが出力されます。

<div class="faq">
  <h3>Q. サービスの料金は?</h3>
  <p>基本プランは月額5,000円です。</p>

  <h3>Q. 解約はできますか?</h3>
  <p>いつでも解約可能です。追加費用はかかりません。</p>
</div>

4. 確認方法


まとめ

  • AIOSEOはFAQスキーマを自動出力するため、自作と干渉する可能性がある
  • add_filterでAIOSEO側を停止
  • wp_headで1つだけFAQ JSON-LDを出力

これで検索エンジンに正しくFAQ構造化データを伝えられます。