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では、送信者がそのサイトの持ち主であることを「キー」で示します。
- 半角英数字とハイフンからなる文字列(8〜128文字)をキーとして決めます。
- そのキーを中身にしたテキストファイルを、
https://example.com/{キー}.txtの場所に置きます。 - 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で結果を確認する。