Как убрать дубли страниц из XML sitemap в WordPress

Если в XML sitemap попадают страницы, которые не должны индексироваться, поисковик тратит краулинговый бюджет на мусорные URL, а в отчётах Search Console появляются странные дубли. На практике это часто не «проблема карты сайта», а следствие того, как тема, плагины и сам WordPress формируют публичные ссылки.

Типичный сценарий: в sitemap оказываются страницы пагинации, вложенные архивы, служебные таксономии, медиа-страницы, тестовые шаблоны или URL с параметрами. Иногда всё выглядит нормально в интерфейсе SEO-плагина, но в выдаче всё равно всплывают лишние адреса, потому что они доступны по прямой ссылке и не исключены из генерации карты сайта.

Что именно нужно искать в первую очередь

Перед правкой кода стоит понять, какой тип дублей у вас есть. Это важно: убрать URL из sitemap и запретить его индексацию — не одно и то же. Если страница остаётся доступной, но не должна участвовать в карте сайта, достаточно исключить её из генерации. Если же URL вообще не нужен, лучше закрыть его на уровне шаблона, редиректа или правил плагина.

Диагностика проблемы

Проверьте sitemap в браузере и найдите повторяющиеся или лишние типы URL:

  • архивы авторов и дат;
  • страницы вложений медиафайлов;
  • страницы пагинации архивов;
  • служебные таксономии без контента;
  • страницы с параметрами, если они попали через кастомный код;
  • дубли записей, если один и тот же контент доступен по нескольким адресам.

Если используется SEO-плагин, сначала проверьте его настройки. У многих плагинов есть отдельные переключатели для типов записей, таксономий и архивов. Но если лишний URL создаёт тема или кастомный плагин, одной галочки в админке может быть недостаточно.

ПодходКогда подходитМинус
Настройки SEO-плагинаНужно быстро убрать стандартные архивы и типы записейНе всегда видит кастомный код
Код через фильтры WordPressНужно точечно исключить URL из sitemapТребует проверки после обновлений
Редирект/закрытие шаблонаURL вообще не должен существоватьНужно аккуратно не сломать внутренние ссылки

Как убрать URL из sitemap через код

В WordPress 5.5+ есть встроенная XML sitemap. Если вы не используете SEO-плагин, исключать URL можно через фильтры ядра. Для отдельных типов записей и таксономий удобно работать через wp_sitemaps_post_types и wp_sitemaps_taxonomies.

Ниже пример, который убирает из sitemap страницы вложений и один служебный тип записи. Код лучше добавить в мини-плагин или в functions.php дочерней темы, если у вас нет отдельного плагина для кастомной логики.

<?php
add_filter('wp_sitemaps_post_types', function ($post_types) {
    if (isset($post_types['attachment'])) {
        unset($post_types['attachment']);
    }

    if (isset($post_types['landing'])) {
        unset($post_types['landing']);
    }

    return $post_types;
});

add_filter('wp_sitemaps_taxonomies', function ($taxonomies) {
    if (isset($taxonomies['post_tag'])) {
        unset($taxonomies['post_tag']);
    }

    return $taxonomies;
});

Если проблема не в типе записей, а в конкретных URL, используйте фильтр wp_sitemaps_posts_entry. Он позволяет исключить отдельные записи из карты сайта по ID, статусу или мета-полю.

<?php
add_filter('wp_sitemaps_posts_entry', function ($entry, $post, $post_type) {
    if ($post_type === 'post' && get_post_meta($post->ID, '_exclude_from_sitemap', true)) {
        return false;
    }

    return $entry;
}, 10, 3);

Такой вариант удобен, если редактору нужно вручную помечать записи как исключённые. Но не делайте это без понятной процедуры: метаполе должно заполняться осознанно, иначе вы сами потеряете важные страницы из карты сайта.

Если sitemap генерирует SEO-плагин

У популярных SEO-плагинов свои механизмы исключения URL. В этом случае не стоит одновременно править и плагин, и ядро WordPress без необходимости: можно получить непредсказуемый результат. Сначала отключите лишнее в настройках плагина, затем проверьте, остались ли дубли в фактическом sitemap.

Практически полезный порядок такой:

  1. отключить архивы и типы записей, которые не должны индексироваться;
  2. убрать медиа-страницы, если они не нужны;
  3. проверить, не создаёт ли тема отдельные шаблоны с публичными URL;
  4. посмотреть, не добавляет ли кастомный код дополнительные ссылки в sitemap;
  5. после изменений очистить кеш, если sitemap кешируется.

Пошаговое решение без лишнего риска

Если нужен рабочий и предсказуемый порядок, делайте так:

  1. Откройте sitemap и выпишите все лишние URL по типам.
  2. Определите источник: ядро WordPress, SEO-плагин, тема или кастомный плагин.
  3. Сначала отключите лишнее в настройках плагина, если это возможно.
  4. Если URL создаёт ядро или кастомный код, добавьте фильтр исключения.
  5. Очистите кеш сайта и CDN, если они есть.
  6. Проверьте sitemap повторно и убедитесь, что URL исчезли.

Если вам нужно убрать из sitemap только вложения, но оставить сами медиафайлы доступными по прямой ссылке, не трогайте медиатеку целиком. Достаточно исключить тип записи attachment из карты сайта и при необходимости закрыть attachment-страницы редиректом на файл или родительскую запись.

<?php
add_action('template_redirect', function () {
    if (is_attachment()) {
        $parent = wp_get_post_parent_id(get_queried_object_id());

        if ($parent) {
            wp_safe_redirect(get_permalink($parent), 301);
            exit;
        }
    }
});

Этот вариант полезен, когда attachment-страницы уже успели попасть в индекс. Но если у вас на них есть реальный контент, редирект может быть неуместен. Сначала проверьте, что именно открывается по таким URL.

Как проверить, что решение сработало

Проверка должна быть не только визуальной. После правок откройте sitemap в браузере и убедитесь, что лишних URL там нет. Затем проверьте исходный код страницы sitemap и убедитесь, что кэш не отдаёт старую версию.

  • Откройте /wp-sitemap.xml или sitemap SEO-плагина.
  • Проверьте, что исключённые типы записей и таксономии отсутствуют.
  • Сделайте запрос на проблемный URL и убедитесь, что он не возвращается в sitemap.
  • Если использовался редирект, проверьте код ответа через DevTools или curl -I.
  • В Search Console дождитесь повторной обработки карты сайта и посмотрите, исчезли ли лишние URL из отчётов.

Для быстрой проверки с сервера удобно использовать:

curl -I https://example.com/wp-sitemap.xml

Если ответ приходит с кеширующим заголовком, а изменения не видны, сначала сбросьте кеш плагина, потом серверный кеш и только затем CDN. Иначе вы будете проверять старую версию карты сайта.

Частые ошибки и как их исправить

Удалили URL из sitemap, но он всё ещё индексируется

Это нормально, если страница доступна по прямой ссылке и на неё ведут внутренние ссылки. Исключение из sitemap не равно удалению из индекса. Для таких URL нужно отдельно решить: оставить страницу доступной, поставить noindex или сделать редирект.

Сломали sitemap после обновления плагина

Если вы правили файлы плагина напрямую, обновление всё перезапишет. Перенесите логику в дочернюю тему или собственный мини-плагин. Это особенно важно для фильтров и исключений, которые должны жить дольше одной версии плагина.

Скрыли слишком много страниц

Частая ошибка — убрать из sitemap целые таксономии или типы записей, не проверив, есть ли там полезные страницы. Если архивы реально дают трафик, не закрывайте их автоматически. Сначала посмотрите, какие URL уже ранжируются и какие из них нужны.

Не учли кеш

Если sitemap отдаётся через кеш, изменения в коде не будут видны сразу. После правок очищайте не только плагин кеширования, но и объектный кеш, если он есть. Для сайтов с CDN это тоже обязательный шаг.

Что делать, если дубли создаёт тема или кастомный плагин

Иногда проблема не в sitemap как таковом, а в том, что тема регистрирует лишние публичные архивы или дублирует ссылки в шаблонах. Тогда нужно искать источник генерации URL: register_post_type(), register_taxonomy(), шаблоны архивов и фильтры, которые добавляют ссылки в навигацию. Если URL не должен существовать, лучше убрать его на уровне регистрации, чем потом пытаться вычищать из sitemap и индекса одновременно.

Для производительности и безопасности это тоже правильнее: меньше публичных URL — меньше мусорных запросов, меньше шансов получить тонкие страницы и лишнюю нагрузку на краулер. Если у вас много служебных страниц и дублей, имеет смысл отдельно пройтись по теме и плагинам, которые их создают, а не лечить только карту сайта.

⭐⭐⭐⭐⭐