Warning: Attempt to read property "ID" on string in /home/xs816122/tokikane.biz/public_html/wp-content/themes/media-theme/inc/cta-inserter.php on line 186

Warning: Attempt to read property "ID" on string in /home/xs816122/tokikane.biz/public_html/wp-content/themes/media-theme/inc/cta-inserter.php on line 190

Warning: Attempt to read property "ID" on string in /home/xs816122/tokikane.biz/public_html/wp-content/themes/media-theme/inc/single-parts.php on line 412

Warning: Attempt to read property "ID" on string in /home/xs816122/tokikane.biz/public_html/wp-content/themes/media-theme/inc/single-parts.php on line 441

Warning: Attempt to read property "ID" on string in /home/xs816122/tokikane.biz/public_html/wp-content/themes/media-theme/inc/cta-inserter.php on line 114
LLMO構造化データの実装|WordPressで@graphを1本に束ねる手順と、自社サイト点検で見つかった7つの穴 LLMO構造化データの実装|WordPressで@graphを1本に束ねる手順と、自社サイト点検で見つかった7つの穴

LLMO構造化データの実装|WordPressで@graphを1本に束ねる手順と、自社サイト点検で見つかった7つの穴

LLMO(大規模言語モデル最適化)向けの構造化データを「入れた」のに、ページのソースを開くと同じ Article が2回出ている。プラグインを止めたら著者情報が消えた。FAQ を直したのに構造化データの中身は古いまま。WordPress で構造化データの実装を進めると、型を選ぶ段階より、その後の「どこから出ているか」「つながっているか」「保たれているか」でつまずきます。本記事は、llmo 構造化データの実装を、当サイト tokikane.biz の本番コードと、2026年10月6日に本番の公開HTMLを点検した結果を材料に、工程として整理します。

この記事の要点

  • 構造化データの実装の本体は、型選びではなく「出力元を1本にして、ノード同士を @id でつなぐ」ことです
  • WordPress では SEOプラグイン・テーマ・ショートコード・自前コードの4系統が同時に出力し得るので、まず棚卸しします
  • 公開後は、ツールの「エラーなし」に加えて「参照切れ」と「同じ型の重複」を検査します。数十行のスクリプトで確認できます
  • dateModified は WordPress の既定では本文更新のたびに動きます。動かす条件を運用ルールとして決めておきます

実装の本体は「どの型を入れるか」ではなく「出力元を1本にして@idでつなぐ」こと

構造化データは、ページの内容を検索エンジンや AI が機械的に読める形で示す記述です。形式は JSON-LD・Microdata・RDFa の3つがあり、Google はサイトの構成が許すなら JSON-LD を推奨しています(Google 検索セントラル「構造化データ マークアップとは」)。

どの型を入れるべきか(Organization・Article・FAQPage など優先すべき型の選び方)と、構造化データで AI 引用が増えるのかという効果の検証は、構造化データとLLMOで扱っています。全体像の入口は構造化データ対策のページです。本記事はその先の「実装工程」だけを扱います。

なお、効果については先に断っておきます。Google は AI による概要(AI Overviews)や AI モードに表示されるために、新しい機械可読ファイルやマークアップを作る必要はないと説明しています(Google 検索セントラル「AI 機能とウェブサイト」)。当サイトには、構造化データを直した結果 AI 引用が増えた・減ったという検証データはありません。本記事が示すのは「正しく出力され、つながり、保たれている状態」を作る手順です。

まず出力元を棚卸しする。WordPressでは4系統が同時に出力し得る

最初にやるのは、いま何が構造化データを出しているかの棚卸しです。WordPress では次の4系統がそれぞれ独立して出力でき、互いの存在を知りません。

出力元 典型例 出るもの 見つけ方
SEOプラグイン Yoast SEO、Rank Math など サイト共通〜記事の基本型をまとめた JSON-LD ページの HTML ソースで application/ld+json を検索し、プラグイン名入りの class や記述を確認
自前コード functions.php、自社プラグイン 自分で組んだ JSON-LD 同上。コード側で wp_head / wp_footer に出力している箇所を検索
テーマ テーマ組込みの構造化データ JSON-LD、または HTML 属性の microdata(itemscope / itemprop) HTML ソースで itemscope を検索
ショートコード・ブロック FAQ ブロック、HowTo ブロック その部品の分だけ独立した JSON-LD 部品を置いたページだけ <script> が増えていないかを比べる

当サイトの場合、2026年10月6日時点で次のようになっていました。

  • SEOプラグイン(Yoast SEO): 導入済みだが、構造化データの出力は止めている
  • 自前コード(自社プラグイン Media Core): @graph 1本で Organization・WebSite・Article・BreadcrumbList などを出力
  • テーマ: 記事本体の article 要素に microdata の Article を付与
  • ショートコード: 本文の FAQ 用ショートコードから FAQPage を別の <script> で出力

4系統のうち3系統が動いていて、そのうち1系統(microdata)は意図して残したものではありませんでした(後述の所見⑥)。棚卸しは「自分のサイトは1系統のはず」という思い込みを外すために、必ず HTML の実物で行います。

Yoastを残して拡張するか、止めて自前で組むかは「自前で出したい型があるか」で決まる

出力元を1本に寄せるとき、SEOプラグインを正にするか、自前コードを正にするかを決めます。Yoast SEO は開発者向けの Schema API を公開しており、残したまま拡張する道と、止めて自前で組む道の両方が用意されています(Yoast developer docs「Schema API」)。

状況 選ぶ道 使う仕組み
サイト共通と記事の基本型で足りる 残す(何もしない) プラグインの設定画面のみ
プラグインが出すノードに項目を足したい 残して拡張 ノードごとのフィルター(wpseo_schema_article、wpseo_schema_webpage など)。自作ノードからは Yoast の固定 ID(Schema_IDs クラス)を参照する
一部のノードだけ要らない 残して一部を外す wpseo_schema_graph_pieces フィルター
投稿タイプごとに独自の型を出し、@id の規約も自分で持ちたい 止めて自前で組む wpseo_json_ld_output フィルターで false か空配列を返すと、Yoast の構造化データ出力がすべて止まる

当サイトは最後の「止めて自前」を選んでいます。記事のほかに、ホワイトペーパーを Report、無料ツールを WebApplication、カテゴリ一覧を ItemList として出したく、それらを1つの @id 規約でつなぎたかったためです。

判断が分かれやすい点を、対比で整理します。

  • 避けたい判断: プラグインを残したまま、テーマや自前コードで同じ Article をもう1本出す
  • こうすればOK: どちらか一方を正にして、もう一方の同じ型は止める。止めたら、同じ型が1回しか出ていないことを HTML で確かめる
  • 避けたい判断: 出力を止めたのに、コードの説明コメントや社内資料は「プラグインが出している」のまま残す
  • こうすればOK: 実装を切り替えたら説明も同時に直す。当サイトでもテーマ側のファイル冒頭に「JSON-LD は Yoast SEO が出力する」という古いコメントが残っており、実態とずれていました

WordPress の LLMO 対策全体(robots.txt、llms.txt、Yoast SEO の基本設定)はLLMO対策のWordPress実装にまとめています。本記事は構造化データの出力系統に絞ります。

@idは「URL+#役割」で固定し、つながりは参照で書く

JSON-LD では、ノードは @id キーワードで識別され、@id だけを持つオブジェクトは文書内の別の場所にあるノードへの参照として扱えます(W3C「JSON-LD 1.1」§1.4・§3.3)。Google も、1ページに複数のアイテムがあり、つなげたほうが役立つ場合は両方に @id を使ってつなぐよう案内しています(Google 検索セントラル「Google 検索上の構造化データ ガイドライン」)。

つまり、Article の中に Organization の情報を毎回書き込むのではなく、Organization は1か所で定義し、Article からは {"@id": "…#organization"} と参照だけを書きます。当サイトでは次の規約にしています(WebPage・Person の行は、後述の所見③⑦の直し方を含めた形です)。

ノード @id 参照する側
Organization(運営組織) https://example.com/#organization WebSite.publisher、Article.publisher
WebSite https://example.com/#website Article.isPartOf、WebPage.isPartOf
WebPage 記事の URL そのもの Article.mainEntityOfPage
Article 記事の URL + #article —
Person(著者) 著者ページの URL + #person Article.author

テキストで結線図にすると、次の形です。

Organization (#organization) ←── publisher ── WebSite (#website)
        ↑ publisher                              ↑ isPartOf
Article (記事URL#article) ── mainEntityOfPage ──→ WebPage (記事URL)
        └── author ──→ Person (著者ページURL#person)

規約は3つだけです。

  1. @id は「URL + #役割」で固定し、全ページで同じ文字列にする。#organization の位置に実際のページ要素が無くても、識別子として機能します
  2. つながりは @id だけを書いた参照で表す。同じ組織や著者の情報を複数箇所に書かない
  3. 参照したら、参照先のノードも同じ出力の中に置く。置かないと、参照はただの URL として読まれ、つなぐ先が無くなります(所見⑦)

組織そのものの実体を外部の公式アカウントと結びつける考え方は、エンティティ対策で扱っています。

functions.phpで@graphを1本組む。tokikane.bizの本番コードの骨格

当サイトの本番では、自社プラグインが wp_head(優先度30)で @graph を1本出力しています。次のコードは、その骨格を functions.php に貼れる形に簡略化したものです。

<?php
/**
 * JSON-LD を @graph 1本で出力する(tokikane.biz の実装を簡略化した骨格)
 */

// 1. Yoast SEO の JSON-LD 出力を止める(出力元を自前の1本に寄せる)
add_filter( 'wpseo_json_ld_output', '__return_empty_array' );

// 2. wp_head で @graph を1本だけ出力する
add_action( 'wp_head', 'mysite_output_jsonld', 30 );

function mysite_output_jsonld() {
    $home  = home_url( '/' );
    $graph = array();

    // 全ページ共通: 運営組織とサイト
    $graph[] = array(
        '@type' => 'Organization',
        '@id'   => $home . '#organization',
        'name'  => get_bloginfo( 'name' ),
        'url'   => $home,
    );
    $graph[] = array(
        '@type'     => 'WebSite',
        '@id'       => $home . '#website',
        'name'      => get_bloginfo( 'name' ),
        'url'       => $home,
        'publisher' => array( '@id' => $home . '#organization' ),
    );

    // 記事ページ: Article を組み、共通ノードへは @id の参照だけを書く
    if ( is_singular( 'post' ) ) {
        $url     = get_permalink();
        $article = array(
            '@type'            => 'Article',
            '@id'              => $url . '#article',
            'headline'         => get_the_title(),
            'url'              => $url,
            'datePublished'    => get_the_date( 'c' ),
            'dateModified'     => get_the_modified_date( 'c' ),
            'mainEntityOfPage' => array( '@id' => $url ),
            'publisher'        => array( '@id' => $home . '#organization' ),
            'isPartOf'         => array( '@id' => $home . '#website' ),
        );
        $graph[] = $article;
    }

    $data  = array(
        '@context' => 'https://schema.org',
        '@graph'   => $graph,
    );
    $flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG;

    echo '<script type="application/ld+json">' . wp_json_encode( $data, $flags ) . '</script>' . "\n";
}

押さえどころは3つです。

  • 止める処理と出す処理を同じファイルに置く。wpseo_json_ld_output で Yoast を止める行と、自前の出力が離れていると、片方だけ消されて「何も出ない」か「二重に出る」状態になります
  • 日付は WordPress の値から取る。書式 c は PHP の日付書式で ISO 8601 を表すので(PHP マニュアル「DateTimeInterface::format」)、get_the_date( 'c' ) と get_the_modified_date( 'c' ) の値は、Google が Article の datePublished / dateModified に求める形式に合います(Google 検索セントラル「記事(Article)の構造化データ」)
  • JSON_HEX_TAG を付ける。PHP のこの定数は < と > を \u003C と \u003E に変換します(PHP マニュアル「JSON 定数」)。JSON_UNESCAPED_SLASHES を付けるとスラッシュがエスケープされないため、タイトルなどに </script> という文字列が混ざると script 要素が途中で閉じてしまいます。当サイトの本番コードは JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES の2つで、JSON_HEX_TAG は本記事の骨格で足したものです

本番ではこの骨格に、著者・アイキャッチ画像・カテゴリ(articleSection)・タグ(keywords)・パンくず(BreadcrumbList)を足し、投稿タイプごとにホワイトペーパー(Report)とツール(WebApplication)を分岐で出しています。組織名は管理画面の設定欄から取り、空ならサイト名に戻す作りです。

FAQPageは本文のFAQから生成し、別の入力欄を持たない

FAQPage は、本文に表示している Q&A から生成し、構造化データ専用の入力欄を別に持たないのが安全です。Google のガイドラインは、構造化データがページ内容を正しく表していること、読者に見えない内容をマークアップしないことを求めています(Google 検索セントラル「Google 検索上の構造化データ ガイドライン」)。本文から作れば、表示と構造化データは同じ情報源から出ます。

当サイトでは、FAQPage の生成元が2つありました。

  1. 自社プラグイン: カスタムフィールド(ACF)に入力した質問と回答から FAQPage を組む
  2. テーマ: 本文の FAQ 用ショートコード(faq_section / faq_item)から FAQPage を組む

両方が動くと FAQPage が二重に出て、しかもカスタムフィールド側は本文の修正が反映されずに中身がずれていきます。そこで「本文に FAQ ショートコードがある記事では、カスタムフィールド版を出さない」という分岐を入れました。

ところが、この分岐の逆側(テーマが「カスタムフィールド版が出るなら自分は譲る」と判断する側)を、カスタムフィールドの「FAQあり」の印だけで判定していたため、別の穴が開きました。2026年8月の時点で、「FAQあり」の印は立っているのに質問が1件も入っていない記事が8本あり、この判定のままではその8本で FAQPage がどこからも出なくなっていました。譲る条件を「カスタムフィールド版が実際に出力されるか」に変えて塞いでいます。

<?php
// カスタムフィールド版の FAQPage を返す。本文に FAQ ショートコードがある記事では出さない
function mysite_faq_from_fields( $post_id ) {
    $post = get_post( $post_id );
    if ( $post && false !== strpos( $post->post_content, '[faq_section' ) ) {
        return null; // 本文(表示されている Q&A)を正とし、二重出力を避ける
    }

    // 「FAQあり」の印ではなく、質問が1件以上入っているかで判定する
    $count = (int) get_post_meta( $post_id, 'faq_items', true );
    if ( $count < 1 ) {
        return null;
    }

    $entities = array();
    for ( $i = 0; $i < $count; $i++ ) {
        $question = get_post_meta( $post_id, "faq_items_{$i}_question", true );
        $answer   = get_post_meta( $post_id, "faq_items_{$i}_answer", true );
        if ( $question && $answer ) {
            $entities[] = array(
                '@type'          => 'Question',
                'name'           => $question,
                'acceptedAnswer' => array(
                    '@type' => 'Answer',
                    'text'  => $answer,
                ),
            );
        }
    }

    return $entities ? array( '@type' => 'FAQPage', 'mainEntity' => $entities ) : null;
}

// テーマ側は「印があるか」ではなく「カスタムフィールド版が実際に出るか」で譲る
function mysite_faq_owned_by_fields( $post_id ) {
    return null !== mysite_faq_from_fields( $post_id );
}

もう1つ、ショートコードの書式の崩れでも FAQ は黙って消えます。当サイトの執筆規約には、質問文を渡す question 属性を付け忘れたまま公開された記事で、FAQ が1問も表示されていなかった記録があります。生成元を本文に一本化したら、書式は執筆規約で固定し、変えるときは抽出側のコードと同時に直します。

公開後は「参照が切れていないか・同じ型が2回出ていないか」を検査する

Google のリッチリザルトテストなどの検証ツールは、構文の誤りや、リッチリザルトに必要なプロパティの欠落を教えてくれます。ツールの操作は構造化データ検証ツールの使い方にまとめています。一方で、「同じ型が別々のブロックから2回出ている」「参照している @id の定義がどこにも無い」は、ページ全体の出力を見比べないと気づきにくい観点です。

そこで当サイトでは、公開中のページの HTML から JSON-LD を抜き出し、ノードと参照を一覧にする小さなスクリプトを使っています。Python の標準ライブラリだけで動きます。

import json, re, sys, urllib.request
from collections import Counter

def fetch(url):
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
    with urllib.request.urlopen(req, timeout=30) as r:
        return r.read().decode("utf-8", "replace")

def walk(obj, defined, refs):
    if isinstance(obj, dict):
        keys = set(obj) - {"@context"}
        if keys == {"@id"}:
            refs.append(obj["@id"])          # 参照だけのノード
        elif "@id" in obj:
            defined.append(obj["@id"])       # 定義されたノード
        for v in obj.values():
            walk(v, defined, refs)
    elif isinstance(obj, list):
        for v in obj:
            walk(v, defined, refs)

def check(url):
    html = fetch(url)
    blocks = re.findall(
        r'<script[^>]*type="application/ld\+json"[^>]*>(.*?)</script>', html, re.S)
    types, defined, refs = Counter(), [], []
    print(f"# {url}")
    print(f"JSON-LDブロック数: {len(blocks)}")
    for i, raw in enumerate(blocks, 1):
        data = json.loads(raw)
        nodes = data.get("@graph", [data])
        for n in nodes:
            t = n.get("@type")
            types[str(t)] += 1
            print(f"  block{i}: {t}  @id={n.get('@id', '(なし)')}")
        walk(data, defined, refs)
    for t, c in types.items():
        if c > 1:
            print(f"[重複] {t} が {c} 回出力されている")
    for r in sorted(set(refs) - set(defined)):
        print(f"[参照切れ] {r} を参照しているが、その@idのノードが無い")
    if "itemscope" in html:
        print(f"[併存] microdata(itemscope)が {html.count('itemscope')} 箇所ある")

for u in sys.argv[1:]:
    check(u)

python3 check_jsonld.py <URL> <URL> … のように URL を並べて実行します。当サイトの記事構造化データとLLMOに2026年10月6日に実行した結果が次です。

# https://tokikane.biz/llmo-tactics/llmo-structured-data-guide/
JSON-LDブロック数: 2
  block1: Organization  @id=https://tokikane.biz/#organization
  block1: WebSite  @id=https://tokikane.biz/#website
  block1: Article  @id=https://tokikane.biz/llmo-tactics/llmo-structured-data-guide/#article
  block1: BreadcrumbList  @id=(なし)
  block2: FAQPage  @id=(なし)
[参照切れ] https://tokikane.biz/llmo-tactics/llmo-structured-data-guide/ を参照しているが、その@idのノードが無い
[併存] microdata(itemscope)が 1 箇所ある

同じ型の重複は出ていません。一方で、参照切れ1件と microdata の併存が見つかりました。穴の多くはテンプレート単位で起きるので、テンプレートごとの代表ページから回すと効率的です。ただし次章の所見①のように記事単位で起きる穴もあるため、記事の一覧に対してまとめて回すことも検討します。なお、itemscope の数は本文中にその文字列を含む記事では多めに出るので、件数ではなく有無の目安として読みます。

tokikane.bizの実出力を点検したら7つの穴があった

2026年10月6日に、当サイトの記事5本・著者ページ・トップページの公開HTMLを取得し、上のスクリプトと目視で点検しました。見つかった穴は次の7つです。いずれも WordPress で自前実装をすると起きやすい種類のものなので、点検の観点として使えます。

# 所見 なぜ問題か 直し方
① Article に author が無い記事がある(点検した5記事のうち2記事) Google は著者を type と url(または sameAs)付きで指定することを強く推奨している 著者の決定を共通関数にまとめ、取れないときは運営組織を著者にするなど、必ず値が入る作りにする
② 編集部名義の著者を Person 型で出している Google は人には Person、組織には Organization を使うよう求めている 編集部名義なら Organization 型にするか、運営組織の #organization を参照する
③ 記事の author が、著者ページにある Person(…/author/tokikane/#person)を参照していない 同じ著者が、記事側と著者ページ側で別々のノードとして出ている author を {"@id": "著者ページURL#person"} の参照にする
④ Organization に sameAs が無い(点検した全ページ) 公式アカウントなど外部の情報源と同じ組織だと示す手段が無い 設定欄はあるが値が出力されていない(未入力と判断)。公式アカウントの URL を入れる
⑤ FAQPage が @graph の外の別ブロックで、@id も無い ルール違反ではない(Google は別ブロックで並べる方法も認めている)が、どの記事の FAQ かをグラフ上で結べない 生成元は本文のまま、出力を @graph 側に寄せる。優先度は低い
⑥ 記事の article 要素に microdata の Article が付いている 禁止ではないが、JSON-LD の Article と結ばれていない2つ目の Article 表現になっている microdata の付与を外し、JSON-LD に一本化する
⑦ Article の mainEntityOfPage が参照する記事 URL のノードがグラフ内に無い 参照は URL としては有効だが、WebPage 側の情報(名前・所属サイト)をつなぐ先が無い WebPage ノードを同じ @graph に置く

②は、構造化データとLLMOの記事内で「編集部名義なら Organization を使う」と書いている一方で、本番の出力は Person になっていた、というずれでもあります。書いた方針と実際の出力は、別々に確かめないと一致しません。

②③⑦は、前章の骨格の記事ページ分岐に次の追加で直せます($graph[] = $article; の行より前に置きます)。

<?php
// 所見②③⑦の直し方(記事ページの分岐の中、$graph[] = $article; の前に置く)
$author_id  = (int) get_post_field( 'post_author', get_the_ID() );
$author_url = get_author_posts_url( $author_id );

// ③ 著者は、著者ページの Person ノードを @id で参照する
//    ② 編集部名義なら Person にせず、array( '@id' => $home . '#organization' ) を参照する
$article['author'] = array( '@id' => $author_url . '#person' );
$graph[] = array(
    '@type' => 'Person',
    '@id'   => $author_url . '#person',
    'name'  => get_the_author_meta( 'display_name', $author_id ),
    'url'   => $author_url,
);

// ⑦ mainEntityOfPage が指す WebPage ノードを同じグラフに置く
$graph[] = array(
    '@type'    => 'WebPage',
    '@id'      => $url,
    'url'      => $url,
    'name'     => get_the_title(),
    'isPartOf' => array( '@id' => $home . '#website' ),
);

うまくいっていた点もあります。Yoast SEO の出力を止めているため Article の重複は出ておらず、Organization・WebSite・Article は @id 付きで結線されていました。記事に表示している公開日・更新日と、JSON-LD の datePublished / dateModified は同じ値から出ていて一致しています。

繰り返しになりますが、これらの穴を直すと AI 引用がどう変わるかのデータは当サイトにはありません。ここでの「穴」は、Google のガイドラインや JSON-LD の仕組みに照らして、出力が意図どおりつながっていない箇所という意味です。

dateModifiedは「本文を実質的に変えたときだけ」動かし、四半期ごとに点検する

WordPress の既定の動きを知らないと、dateModified の運用は形だけになります。get_the_modified_date() は投稿の最終更新日を返します。投稿を更新する wp_update_post() は内部で wp_insert_post() を呼び、wp_insert_post() は更新のたびに最終更新日時を現在時刻にします(WordPress Developer Resources)。一方、update_post_meta() はメタ情報を更新するだけで、この処理を通りません。

Google は、ページが公開された日や大きく更新された日を複数の要素から推定するとしたうえで、表示している日付と構造化データの日付を一致させるよう求めています(Google 検索セントラル「Google 検索の検索結果に署名日を追加する」)。この2点から、当サイトでは次のルールにしています。

変更の種類 WordPress での典型的な操作 既定で dateModified は動くか 運用ルール
本文の実質的な改稿(情報の追加・訂正) 編集画面で更新 / wp_update_post() 動く 動いてよい。表示の更新日も同じ値から出す
誤字の修正・リンクの差し替え 同上 動く 単独では行わず、次の実質的な改稿とまとめて反映する
title・meta description だけの変更 (a)編集画面の Yoast 欄を変えて「更新」 / (b)WP-CLI 等から update_post_meta() で直接書く (a)動く(投稿の保存処理を通るため) / (b)動かない 本文は変わっていないので動かさなくてよい。動かしたくなければ(b)でメタだけを更新する
構造化データやテーマのコード変更 テーマ・プラグインの更新 動かない 記事の内容は変わっていないので動かさない

公開後の点検は、四半期に1回を目安にしています。中身は次の4つです。

  1. テンプレートごとの代表ページに検査スクリプトを回し、重複・参照切れ・併存の有無を前回と比べる
  2. 表示している更新日と JSON-LD の dateModified が一致しているかを確かめる
  3. Search Console の構造化データ関連のレポートで、エラーと警告の増減を見る(読み方は構造化データ検証ツールの使い方)
  4. SEOプラグインやテーマを更新した直後は、四半期を待たずに1と2を回す。更新で出力が復活・変化することがあるため

まとめ

  • llmo 構造化データの実装は、型を選んだ後の「出力元を1本にして @id でつなぐ」工程が本体です。型の選び方と効果は構造化データとLLMOに委ねます
  • WordPress では SEOプラグイン・自前コード・テーマ・ショートコードの4系統が同時に出力し得ます。HTML の実物で棚卸しし、正にする1系統を決めます
  • @id は「URL + #役割」で固定し、つながりは参照で書き、参照先のノードは同じ出力の中に置きます
  • FAQPage は本文の FAQ から生成し、別の入力欄を持たないようにします。入力欄の二重化は、FAQPage の重複と消失の両方を招きました
  • 公開後は、ツールの判定に加えて、重複・参照切れ・microdata の併存をスクリプトで検査します。当サイトの点検では7つの穴が見つかりました
  • dateModified は既定では本文更新のたびに動くので、動かす条件を運用ルールとして決めます

自社サイトの構造化データが、構造化データ以外の要素も含めてどこまで整っているかは、LLMO対応度診断ツール(無料・登録不要)で確認できます。手作業の棚卸しと組み合わせると、どこから直すかの当たりをつけやすくなります。

よくある質問(FAQ)

よくある質問


QYoast SEOの構造化データ出力を止めても問題ありませんか?
A

止めた分を自前で出力するのであれば問題ありません。Yoast SEO の開発者向けドキュメントでは、wpseo_json_ld_output フィルターで false か空配列を返すと、Yoast SEO の構造化データ出力がすべて止まると説明されています。止めると Organization・WebSite・Article などもまとめて消えるため、先に自前の出力を用意してから止め、公開HTMLで同じ型が1回ずつ出ていることを確かめてください。基本の型だけで足りるなら、止めずに Yoast SEO を正にするほうが手間は少なく済みます。


QSEOプラグインとテーマの両方が構造化データを出している場合、どちらを止めればよいですか?
A

出したい型をすべて出せて、@id の規約を自分で決められる側を残し、もう一方の同じ型を止めます。基本の型だけで足りるならSEOプラグインを残し、テーマ側の出力を止めるのが手軽です。投稿タイプごとに独自の型を出したい場合は、自前コード側を残してプラグインの出力を止めます。どちらを選んでも、最後はページのHTMLで application/ld+json と itemscope を検索し、同じ型が2回出ていないことを確認してください。


Q構造化データの@idは実在するページのURLでなければいけませんか?
A

必ずしも実在するページ要素を指す必要はありません。@id はノードを識別するためのもので、当サイトでは https://example.com/#organization のように、サイトのURLに「#役割」を付けた形に固定しています。大事なのは、同じ組織や著者には全ページで同じ文字列を使い続けることと、参照した@idのノードを同じ出力の中に置くことです。ページごとに@idが変わると、同じ組織が別々のものとして扱われる原因になります。


QFAQPageの構造化データは@graphに入れるべきですか、別のscriptタグでもよいですか?
A

どちらでも構いません。Google のガイドラインは、1ページの複数のアイテムを入れ子にする方法と、別々のブロックで並べる方法の両方を認めています。@graph に入れると記事やページと@idで結べる利点がありますが、それより効くのは、FAQPage の生成元を本文に表示しているQ&Aの1か所にすることです。生成元が2つあると、二重出力と中身のずれの両方が起きます。


QmicrodataとJSON-LDが同じページに両方あると問題ですか?
A

併用自体は禁止されていません。Google は JSON-LD・Microdata・RDFa のいずれにも対応しており、そのうえでJSON-LDを推奨しています。ただし同じ記事を microdata と JSON-LD の両方で別々に記述し、@idで結んでいない場合、同じものの表現が2つある状態になります。テーマが意図せず microdata を付けていることもあるため、どちらかに一本化するのが管理しやすい形です。


Q構造化データの実装を直すと、AI検索で引用されやすくなりますか?
A

当サイトには、構造化データを直してAI引用が増えた・減ったという検証データはありません。Google は、AI による概要やAIモードに表示されるために新しいマークアップなどを用意する必要はないと説明しています。構造化データの実装の目的は、ページの情報を正しく、つながった形で機械に渡すことです。AI引用への効果を外部の一次研究で検証した内容は、構造化データとLLMOの記事で詳しく扱っています。



出典

  1. Google 検索セントラル「構造化データ マークアップとは」(2026-10-06 取得)
  2. Google 検索セントラル「Google 検索上の構造化データ ガイドライン」(2026-10-06 取得)
  3. Google 検索セントラル「記事(Article)の構造化データ」(2026-10-06 取得)
  4. Google 検索セントラル「Google 検索の検索結果に署名日を追加する」(2026-10-06 取得)
  5. Google 検索セントラル「AI 機能とウェブサイト」(2026-10-06 取得)
  6. W3C「JSON-LD 1.1」(2026-10-06 取得)
  7. schema.org「mainEntityOfPage」(2026-10-06 取得)
  8. Yoast developer docs「Schema API」(2026-10-06 取得)
  9. WordPress Developer Resources「wp_update_post()」(2026-10-06 取得)
  10. WordPress Developer Resources「wp_insert_post()」(2026-10-06 取得)
  11. WordPress Developer Resources「get_the_modified_date()」(2026-10-06 取得)
  12. WordPress Developer Resources「update_post_meta()」(2026-10-06 取得)
  13. PHP マニュアル「JSON 定数」(2026-10-06 取得)
  14. PHP マニュアル「DateTimeInterface::format」(2026-10-06 取得)