2026年5月20日

2026年5月20日

WordPressにJSON-LDの構造化データを追加する方法|ArticleとBreadcrumbList

構造化データは、ページの内容(記事の題名・公開日・著者・パンくずの階層など)を検索エンジンが読み取りやすい形で書き添えるものです。Google は JSON-LD・microdata・RDFa の3形式を読み取り、その中で JSON-LD を推奨しています。JSON-LD は <script type="application/ld+json"> の中に JSON で書くため、本文の HTML に手を加えずに追加できます。

この記事では、WordPress の投稿に Article(記事)と BreadcrumbList(パンくずリスト)の JSON-LD を出力するコードを紹介します。Google のプロパティの説明は、2026年10月時点の Google 検索セントラルのドキュメントで確認しています。

追加する前に確認すること

SEOプラグインがすでに出力していないか

Yoast SEO・Rank Math・All in One SEO などの SEO プラグインは、記事やパンくずの構造化データを自動で出力します。同じ種類のデータを自作のコードでも出すと、内容の違う2つのデータが並び、どちらを正とすべきか分かりにくくなります。

まず公開中の記事を開き、ブラウザーの「ページのソースを表示」で application/ld+json を検索してください。すでに Article や BreadcrumbList が出ている場合は、プラグインの設定で調整し、この記事のコードは使わないでください。

構造化データで表示が約束されるわけではない

構造化データは検索エンジンへの手がかりで、追加してもリッチリザルト(検索結果の装飾された表示)が出るとは限りません。また、マークアップはページに実際に表示している内容と一致させる必要があります。Google のガイドラインに反するマークアップは、手動による対策の対象になることがあります。

FAQPage は Google 検索で使われなくなった

以前は FAQPage の構造化データで、検索結果に質問と回答の折りたたみ表示が出ることがありました。Google は2023年にこの表示を政府・医療の権威あるサイトに限り、2026年5月7日からは Google 検索で表示しなくなりました(Google 検索セントラルの FAQ のページによる)。2026年10月時点で、Google のリッチリザルトを目的に FAQPage を追加する意味はありません。

コードを置く場所

以下のコードは、子テーマの functions.php か、コードスニペット用のプラグインに追加します。親テーマの functions.php に書くと、テーマの更新で消えます。編集の前に、ファイルのバックアップを取ってください。

共通の出力関数

JSON-LD を <script> タグとして出力する関数を先に用意します。

<?php
/**
 * 配列を JSON-LD の script タグとして出力する。
 */
function wpdr_print_json_ld( array $data ): void {
	$json = wp_json_encode(
		$data,
		JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG
	);

	if ( false === $json ) {
		return;
	}

	echo '<script type="application/ld+json">' . $json . '</script>' . "\n";
}

JSON_HEX_TAG は、データの中の < と > を、JSON の Unicode エスケープ \u003C と \u003E に置き換える指定です(JSON として読み取ると元の文字に戻ります)。これがないと、記事の題名などに </script> という文字列が含まれていた場合に、そこで script タグが閉じてしまいます。JSON_UNESCAPED_UNICODE は日本語を \uXXXX に変換せずそのまま出す指定、JSON_UNESCAPED_SLASHES は URL の / を \/ にしない指定です。

Article(記事)の構造化データ

Google の Article のドキュメントでは、必須のプロパティはなく、次のプロパティが推奨されています。

プロパティ 内容
headline 記事の題名
datePublished 公開日時(ISO 8601 形式)
dateModified 更新日時(ISO 8601 形式)
author 著者(Person または Organization)。name と url を付ける
image 記事に関係する画像の URL

投稿の詳細ページで、これらを出力するコードです。

<?php
add_action( 'wp_head', function (): void {
	if ( ! is_singular( 'post' ) ) {
		return;
	}

	$post_id   = get_queried_object_id();
	$author_id = (int) get_post_field( 'post_author', $post_id );

	$data = array(
		'@context'         => 'https://schema.org',
		'@type'            => 'Article',
		'headline'         => wp_strip_all_tags( get_post_field( 'post_title', $post_id ) ),
		'datePublished'    => get_the_date( 'c', $post_id ),
		'dateModified'     => get_the_modified_date( 'c', $post_id ),
		'mainEntityOfPage' => get_permalink( $post_id ),
		'author'           => array(
			'@type' => 'Person',
			'name'  => get_the_author_meta( 'display_name', $author_id ),
			'url'   => get_author_posts_url( $author_id ),
		),
		'publisher'        => array(
			'@type' => 'Organization',
			'name'  => get_bloginfo( 'name' ),
			'url'   => home_url( '/' ),
		),
	);

	if ( has_post_thumbnail( $post_id ) ) {
		$image_url = wp_get_attachment_image_url( get_post_thumbnail_id( $post_id ), 'full' );
		if ( $image_url ) {
			$data['image'] = array( $image_url );
		}
	}

	wpdr_print_json_ld( $data );
} );

コードのポイントは次のとおりです。

  • get_the_date( 'c', … ) は、サイトのタイムゾーン付きの ISO 8601 形式(例: 2026-10-30T09:00:00+09:00)で日時を返します。
  • 題名は get_the_title() ではなく、保存されている題名をそのまま取り、HTML タグを除いています。get_the_title() は表示用の整形で & などを文字参照に変えることがあるためです。
  • author.url には著者のプロフィールページなど、著者を示すページの URL を入れます。ここでは投稿者アーカイブの URL を使っています。SEO プラグインなどで投稿者アーカイブを無効にしている場合は、表示できるプロフィールページの URL に替えてください。
  • 画像はアイキャッチ画像のフルサイズを使っています。Google は、記事に関係する高解像度の画像(幅×高さが5万ピクセル以上)を勧めています。ロゴは記事の画像として使わないでください。
  • @type は、ブログ記事なら BlogPosting、ニュース記事なら NewsArticle にしてもかまいません。

BreadcrumbList(パンくずリスト)の構造化データ

Google のパンくずのドキュメントでは、BreadcrumbList に ListItem を2つ以上並べ、各 ListItem に position(1から始まる順番)・name・item(URL)を付けます。最後の項目(現在のページ)は item を省略でき、省略すると Google はそのページの URL を使います。

次のコードは「ホーム → カテゴリー(親カテゴリーを含む) → 記事」の階層を出力します。

<?php
add_action( 'wp_head', function (): void {
	if ( ! is_singular( 'post' ) ) {
		return;
	}

	$post_id = get_queried_object_id();
	$crumbs  = array(
		array(
			'name' => 'ホーム',
			'item' => home_url( '/' ),
		),
	);

	$categories = get_the_category( $post_id );
	if ( $categories ) {
		$category = $categories[0];
		$term_ids = array_reverse( get_ancestors( $category->term_id, 'category', 'taxonomy' ) );
		$term_ids[] = $category->term_id;

		foreach ( $term_ids as $term_id ) {
			$term = get_term( $term_id, 'category' );
			if ( ! $term instanceof WP_Term ) {
				continue;
			}
			$link = get_term_link( $term );
			if ( is_wp_error( $link ) ) {
				continue;
			}
			$crumbs[] = array(
				'name' => wp_specialchars_decode( $term->name, ENT_QUOTES ),
				'item' => $link,
			);
		}
	}

	$crumbs[] = array(
		'name' => wp_strip_all_tags( get_post_field( 'post_title', $post_id ) ),
	);

	$items = array();
	foreach ( $crumbs as $index => $crumb ) {
		$items[] = array_merge(
			array(
				'@type'    => 'ListItem',
				'position' => $index + 1,
			),
			$crumb
		);
	}

	wpdr_print_json_ld( array(
		'@context'        => 'https://schema.org',
		'@type'           => 'BreadcrumbList',
		'itemListElement' => $items,
	) );
} );
  • 記事に複数のカテゴリーがある場合は、get_the_category() が返す最初のカテゴリーを使います。ページに表示しているパンくずと同じカテゴリーになるよう、必要に応じて選び方を変えてください。
  • 「ホーム」の部分は、ページのパンくずに表示している文言に合わせます。
  • カテゴリー名は保存時に & が &amp; などの文字参照になっているため、wp_specialchars_decode() で元の文字に戻しています。

出力を確かめる

  1. 記事を開き、「ページのソースを表示」で application/ld+json を検索して、2つの script タグが出ていることと、日本語が読める形で出ていることを確かめます。キャッシュ系のプラグインを使っている場合は、キャッシュを削除してから確認します。
  2. Google の「リッチリザルト テスト」(https://search.google.com/test/rich-results)に記事の URL を入れ、Article とパンくずリストがエラーなく検出されるか確かめます。
  3. schema.org の書き方として正しいかは、「Schema Markup Validator」(https://validator.schema.org/)でも確認できます。
  4. 公開後は、Google Search Console の拡張機能のレポートで、パンくずリストのエラーが出ていないかを見ます。

PHP の構文エラーがあるとサイト全体が表示されなくなることがあります。追加後はトップページと記事ページが表示されるか確認し、問題があれば FTP やファイルマネージャーで追加した部分を削除してください。

まとめ

  • JSON-LD は wp_head フックから <script type="application/ld+json"> として出力できる。wp_json_encode() に JSON_HEX_TAG を付けて、題名などに含まれる </script> で壊れないようにする。
  • Article は headline・datePublished・dateModified・author(name と url)・image を、BreadcrumbList は position・name・item を付ける。
  • SEO プラグインがすでに出力している種類は、自作のコードで重ねて出さない。
  • FAQPage は2026年5月から Google 検索で表示されなくなっている。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲