2026年8月30日

2026年8月30日

WordPressのサイトマップを最適化してSEOを強化する方法

はじめに

WordPressのサイトマップはGoogleなどの検索エンジンにサイトの構造を伝える重要なファイルです。WordPress 5.5以降は標準でXMLサイトマップ機能が内蔵されましたが、カスタム投稿タイプの除外・優先度設定・Google Search Consoleへの自動送信など、より高度な最適化が必要な場合があります。

症状・原因

  • Google Search Consoleで「サイトマップを送信できませんでした」と表示される
  • 不要なページ(タグ・作者ページなど)がサイトマップに含まれている
  • カスタム投稿タイプがサイトマップに表示されない
  • サイトマップのURLが/sitemap.xmlでアクセスできない

解決手順

ステップ1:WordPress標準サイトマップをカスタマイズする

// functions.php: 不要なサイトマップを無効化
add_filter('wp_sitemaps_enabled', '__return_true');

// タグ・作者ページをサイトマップから除外
add_filter('wp_sitemaps_taxonomies', function(array $taxonomies): array {
    unset($taxonomies['post_tag']);   // タグを除外
    return $taxonomies;
});

add_filter('wp_sitemaps_users_show_on_front', '__return_false'); // 作者ページを除外

add_filter('wp_sitemaps_post_types', function(array $post_types): array {
    unset($post_types['attachment']); // メディアページを除外
    return $post_types;
});

// 特定の投稿をサイトマップから除外(noindexページなど)
add_filter('wp_sitemaps_posts_query_args', function(array $args, string $post_type): array {
    if ($post_type === 'page') {
        // 特定IDのページを除外
        $args['post__not_in'] = array_filter([
            (int) get_option('page_for_posts'),
        ]);
        // _noindexメタがあるページを除外
        $args['meta_query'] = [
            'relation' => 'OR',
            ['key' => '_noindex', 'compare' => 'NOT EXISTS'],
            ['key' => '_noindex', 'value' => '1', 'compare' => '!='],
        ];
    }
    return $args;
}, 10, 2);

ステップ2:カスタムサイトマッププロバイダーを作成する

// Google News向けカスタムサイトマッププロバイダー
class News_Sitemap_Provider extends WP_Sitemaps_Provider {

    public function __construct() {
        $this->name        = 'news';
        $this->object_type = 'post';
    }

    public function get_url_list(int $page_num, string $object_subtype = ''): array {
        // Google Newsは48時間以内の記事のみ対象
        $posts = get_posts([
            'post_type'      => 'post',
            'posts_per_page' => 100,
            'date_query'     => [['after' => '2 days ago']],
            'post_status'    => 'publish',
            'no_found_rows'  => true,
        ]);

        return array_map(fn($post) => [
            'loc'     => get_permalink($post),
            'lastmod' => get_the_modified_date('Y-m-d\TH:i:sP', $post),
        ], $posts);
    }

    public function get_max_num_pages(string $object_subtype = ''): int {
        return 1; // 1ページのみ
    }
}

// プロバイダーを登録
add_action('init', function(): void {
    wp_get_sitemap_registry()->add_provider('news', new News_Sitemap_Provider());
});

ステップ3:サイトマップに画像情報を追加する

// サイトマップのエントリに画像URLを追加(画像検索流入を増加)
add_filter('wp_sitemaps_posts_entry', function(array $entry, WP_Post $post): array {
    $images = [];

    // アイキャッチ画像
    if (has_post_thumbnail($post)) {
        $images[] = [
            'loc'     => get_the_post_thumbnail_url($post, 'large'),
            'caption' => get_the_title($post),
        ];
    }

    // 本文中の画像を抽出(最大5枚まで)
    preg_match_all('/<img[^>]+src=["\']([^"\']+)["\']/', $post->post_content, $matches);
    foreach (array_slice(array_unique($matches[1]), 0, 5) as $img_url) {
        if (!str_starts_with($img_url, 'http')) {
            $img_url = home_url($img_url);
        }
        if (!in_array($img_url, array_column($images, 'loc'), true)) {
            $images[] = ['loc' => $img_url];
        }
    }

    if ($images) {
        $entry['images'] = $images;
    }

    return $entry;
}, 10, 2);

ステップ4:Google Search Consoleへ自動送信する

// 記事公開時にGoogleへサイトマップURLを送信
add_action('publish_post', function(int $post_id): void {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return;

    // 本番環境のみ送信
    if (wp_get_environment_type() !== 'production') return;

    $sitemap_url = urlencode(home_url('/wp-sitemap.xml'));
    wp_remote_get(
        "https://www.google.com/ping?sitemap={$sitemap_url}",
        ['timeout' => 10, 'blocking' => false] // 非ブロッキング送信
    );
});

// サイトマップのHTTPキャッシュヘッダーを設定
add_action('template_redirect', function(): void {
    if (!is_sitemap()) return;
    header('Cache-Control: public, max-age=3600, s-maxage=86400');
    header('Vary: Accept-Encoding');
});

ステップ5:サイトマップのパフォーマンスを最適化する

// サイトマッククエリを最適化してDB負荷を軽減
add_filter('wp_sitemaps_posts_query_args', function(array $args, string $post_type): array {
    // 不要なクエリを省略
    $args['no_found_rows']              = true;  // COUNTクエリ不要
    $args['update_post_meta_cache']     = false; // メタキャッシュ不要
    $args['update_post_term_cache']     = false; // タームキャッシュ不要
    $args['update_post_author_cache']   = false; // 著者キャッシュ不要
    return $args;
}, 10, 2);

// 投稿更新時にサイトマップキャッシュをリセット
add_action('save_post', function(int $post_id): void {
    if (wp_is_post_revision($post_id)) return;

    // オブジェクトキャッシュをクリア
    wp_cache_delete('wp_sitemaps_index', 'sitemaps');
    wp_cache_delete('wp_sitemaps_post_types', 'sitemaps');

    // ページキャッシュプラグインのキャッシュをクリア
    if (function_exists('rocket_clean_domain')) {
        rocket_clean_domain();
    }
});

注意事項

  • noindexページの除外: robots.txtでDisallowしているURLや、noindexメタタグを設定しているページはサイトマップから除外してください
  • URL数制限: 1つのサイトマップファイルには最大50,000URLまでです。大規模サイトではサイトマップインデックスを使用してください
  • プラグインとの競合: Yoast SEO・RankMathを使用している場合はadd_filter('wp_sitemaps_enabled', '__return_false')でWordPress標準を無効化し、プラグイン側の設定を優先してください

まとめ

WordPressサイトマップ最適化の手順は「不要ページの除外設定→カスタムプロバイダーの実装→画像情報の追加→Search Consoleへの自動送信→クエリパフォーマンスの最適化」の5ステップです。関連記事:WordPressのCore Web Vitalsを改善する方法

お気軽にご相談ください

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