2026年10月4日

2026年10月4日

WordPressでIndexNowを使い、記事の公開・更新をBingへすぐ通知する方法

WordPressで記事を公開・更新したときにBingへすぐ知らせたいなら、IndexNowという仕組みを使います。サイトに確認用のキーファイルを置き、変更があったURLをIndexNowのAPIへ送るだけで、Bingなど対応する検索エンジンにクロールのきっかけを伝えられます。この記事では、IndexNowで何ができて何ができないか、プラグインで設定する方法、プラグインを使わずにコードで送る方法、送信結果の確かめ方までを解説します。

IndexNowで何ができるか

IndexNowは、サイト側から「このURLが追加・更新・削除された」と検索エンジンへ知らせるための公開プロトコルです。Microsoft Bing と Yandex などが参加しており、参加している検索エンジンのどれか1つに送れば、他の参加エンジンとも共有される仕組みになっています。

できること・できないことを整理しておきます。

  • できること:検索エンジンがサイトを巡回するのを待たずに、変更のあったURLを伝えられます。ニュースやセール情報など、更新をすぐ反映させたいページで効果を感じやすい仕組みです。
  • できないこと:通知したURLがすぐにインデックスされる、検索順位が上がる、といった保証はありません。クロールするか、インデックスに入れるかは検索エンジンが判断します。
  • Googleとの関係:Googleは、2026年10月現在、IndexNowに参加していないとされています。Googleへの更新の伝達は、従来どおりXMLサイトマップと Search Console で行います。

IndexNowは、サイトマップの代わりではなく、サイトマップに加えて使う「変更のお知らせ」と考えると位置付けが分かりやすくなります。

仕組み:キーとキーファイル

IndexNowでは、送信者がそのサイトの持ち主であることを「キー」で示します。

  1. 半角英数字とハイフンからなる文字列(8〜128文字)をキーとして決めます。
  2. そのキーを中身にしたテキストファイルを、https://example.com/{キー}.txt の場所に置きます。
  3. URLを送るとき、同じキーをAPIに渡します。検索エンジンはキーファイルを読み、中身が一致すれば送信を受け付けます。

キーは推測されにくい値にしてください。WordPressでは wp_generate_password( 32, false ) で記号を含まない32文字を作れます。キーファイルは公開されるものなので秘密情報ではありませんが、他人がこのキーを使えば、あなたのサイトのURLを勝手に通知できてしまいます。漏れたと感じたら作り直します。

方法1:プラグインで設定する

設定の手間を減らしたいなら、プラグインを使うのが手早い方法です。代表的なものは次のとおりです(2026年10月現在)。

  • Microsoft 公式の「IndexNow」プラグイン:有効化するとキーの作成と配置を自動で行い、公開・更新・削除のたびに通知します。
  • SEOプラグインのIndexNow機能:Rank Math などのSEOプラグインには、IndexNowによる通知機能を持つものがあります。すでにSEOプラグインを使っているなら、別のプラグインを足す前に、手持ちのプラグインに機能があるかを確認してください。

同じ通知を複数のプラグインから送ると、重複した送信になります。どれか1つに絞ることが大切です。機能名や設定画面の場所は版によって変わるため、各プラグインの説明ページで確認してください。

方法2:コードで送信する

プラグインを増やしたくない場合や、送るURLを細かく制御したい場合は、自前で送信します。コードはテーマに依存しないよう、mu-plugin(wp-content/mu-plugins/my-indexnow.php)に置くのがおすすめです。作業前にはバックアップを取り、ステージング環境で試してください。

まず、wp-config.php にキーを定数で書き、同じキーを中身にしたファイルをサイトのルート(wp-config.php ではなく、トップページと同じ公開ディレクトリ)に置きます。

// wp-config.php
define( 'MY_INDEXNOW_KEY', 'your-indexnow-key-32chars-example' );

次に、公開中の記事が保存されたら送信を予約し、予約した処理の中でAPIを呼び出します。

<?php
defined( 'ABSPATH' ) || exit;

/**
 * 公開中の投稿が保存されたら、通知を予約する。
 */
function my_indexnow_queue( $post_id, $post, $update, $post_before ) {
	if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
		return;
	}
	if ( ! is_post_type_viewable( $post->post_type ) ) {
		return;
	}
	$was_public = $post_before && 'publish' === $post_before->post_status;
	if ( 'publish' !== $post->post_status && ! $was_public ) {
		return; // 下書きの保存などは送らない。
	}
	// 公開から非公開・ゴミ箱にした場合は、元のURLを送って削除を伝える。
	$url = ( 'publish' === $post->post_status ) ? get_permalink( $post ) : get_permalink( $post_before );

	// 短時間の連続保存をまとめる。
	$lock = 'my_indexnow_' . md5( $url );
	if ( get_transient( $lock ) ) {
		return;
	}
	set_transient( $lock, 1, 5 * MINUTE_IN_SECONDS );

	wp_schedule_single_event( time() + 60, 'my_indexnow_send', array( $url ) );
}
add_action( 'wp_after_insert_post', 'my_indexnow_queue', 10, 4 );

/**
 * IndexNow API へ送信する。
 */
function my_indexnow_send( $url ) {
	if ( 'production' !== wp_get_environment_type() || ! defined( 'MY_INDEXNOW_KEY' ) ) {
		return; // 本番以外からは送らない。
	}
	$host = wp_parse_url( home_url(), PHP_URL_HOST );

	$response = wp_remote_post( 'https://api.indexnow.org/indexnow', array(
		'timeout' => 10,
		'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
		'body'    => wp_json_encode( array(
			'host'        => $host,
			'key'         => MY_INDEXNOW_KEY,
			'keyLocation' => home_url( '/' . MY_INDEXNOW_KEY . '.txt' ),
			'urlList'     => array( $url ),
		) ),
	) );

	$code = is_wp_error( $response ) ? $response->get_error_message() : wp_remote_retrieve_response_code( $response );
	if ( ! in_array( $code, array( 200, 202 ), true ) ) {
		error_log( 'IndexNow: ' . $url . ' => ' . $code );
	}
}
add_action( 'my_indexnow_send', 'my_indexnow_send' );

コードの考え方を補足します。

  • **wp_after_insert_post を使う理由**:WordPress 5.6 で追加されたこのフックは、タームやメタの保存が終わった後に一度だけ呼ばれます。save_post よりも、パーマリンクが確定した状態で処理できます。
  • 送信を予約する理由:保存の処理中に外部APIを待つと、編集画面の保存が遅くなります。wp_schedule_single_event() で1分後に回し、保存の操作を軽く保っています。WP-Cron を止めているサイトでは、サーバーのcronから wp-cron.php を実行する設定が必要です。
  • 本番以外から送らない:ステージング環境のURLを通知すると、テスト用のページがクロールされるきっかけになります。wp-config.php の WP_ENVIRONMENT_TYPE で環境を区別し、本番だけ送るようにしています。
  • 送るURLを絞る:IndexNowは、実際に変化があったURLだけを送ることを求めています。誤字の修正のたびに送っても問題にはなりにくいものの、更新していないページをまとめて定期的に送るような使い方は避けます。一度に複数のURLを送るときは urlList に並べます。

送信結果の読み方

APIの応答コードで、送信がどう扱われたかが分かります。

  • 200:受け付けられました。
  • 202:受け付けられましたが、キーの確認がまだ終わっていません。初回の送信でよく見られます。
  • 400:リクエストの形式が正しくありません。JSONの形やヘッダーを見直します。
  • 403:キーが無効です。キーファイルが https://ドメイン/{キー}.txt で開けるか、中身がキーと一致しているかを確認します。
  • 422:送ったURLが host のドメインと一致しない、またはキーと合いません。www の有無や http と https の違いがよくある原因です。
  • 429:送信が多すぎます。間隔を空け、送るURLを絞ります。

キーファイルは、ブラウザで直接開いてキーだけが表示されれば正常です。セキュリティ系のプラグインやサーバーの設定でルートの .txt ファイルへのアクセスを止めていると、403 の原因になります。

Bing側での受信状況は、Bing Webmaster Tools にサイトを登録しておくと、IndexNow の送信履歴として確認できます(画面の表記は変わることがあります)。Bing Webmaster Tools には IndexNow とは別に独自の URL 送信機能もありますが、WordPressから自動で送るならIndexNowのほうが設定が簡単です。

まとめ

  • IndexNowは、URLの追加・更新・削除を参加している検索エンジンへ知らせる仕組み。Bingに送れば他の参加エンジンにも共有される。
  • インデックスや順位の保証はなく、Google向けにはサイトマップと Search Console を引き続き使う。
  • 手早く済ませるなら Microsoft 公式のIndexNowプラグインか、SEOプラグインの機能を1つだけ使う。
  • 自前で送るなら、wp_after_insert_post で予約し、本番環境からだけ、変化のあったURLを送る。
  • 403・422 はキーファイルとドメインの不一致が主な原因。応答コードとBing Webmaster Toolsで結果を確認する。

お気軽にご相談ください

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