Как отключить XML sitemap для отдельных страниц в WordPress

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

Здесь важно не путать две задачи: убрать страницу из карты сайта и запретить индексацию. Это разные механики. Иногда достаточно исключить URL из sitemap, а иногда нужно еще поставить noindex и закрыть внутренние ссылки. Ниже — рабочие варианты для WordPress без выдуманных хуков и без опасных правок ядра.

Когда проблема действительно в XML sitemap

Проверка начинается не с плагина, а с самой карты сайта. Откройте /sitemap.xml или адрес, который использует ваш SEO-плагин, и найдите спорный URL. Если он там есть, поисковый робот получает прямой сигнал к обходу. Если URL отсутствует, а в индексе он все равно всплывает, проблема уже не в sitemap, а в внутренних ссылках, каноникале или старых внешних ссылках.

Что обычно попадает в карту сайта ошибочно

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

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

Как убрать отдельную страницу из XML sitemap через код

Для WordPress с ядровым генератором sitemap можно использовать фильтр wp_sitemaps_posts_query_args. Он позволяет изменить запрос, который собирает записи для карты сайта. Подходит, если нужно исключить конкретные ID или типы записей.

add_filter( 'wp_sitemaps_posts_query_args', function( $args, $post_type ) {
	$exclude_ids = array( 123, 456 );

	if ( 'page' === $post_type ) {
		$args['post__not_in'] = isset( $args['post__not_in'] )
			? array_merge( $args['post__not_in'], $exclude_ids )
			: $exclude_ids;
	}

	return $args;
}, 10, 2 );

Этот вариант полезен, когда у вас есть несколько служебных страниц и вы точно знаете их ID. Но у него есть минус: ID приходится поддерживать вручную. Если страницу удалят и создадут заново, ID изменится.

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

add_filter( 'wp_sitemaps_posts_entry', function( $entry, $post ) {
	if ( 'page' === $post->post_type && 'thank-you' === $post->post_name ) {
		return false;
	}

	return $entry;
}, 10, 2 );

Здесь логика простая: если slug страницы равен thank-you, запись не попадет в карту сайта. Это удобнее, чем завязываться на ID, если структура сайта меняется.

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

У популярных SEO-плагинов свои механизмы исключения. В этом случае сначала ищите настройку на уровне записи, а не лезьте в код. Например, у многих плагинов можно отключить индексацию конкретной страницы и одновременно убрать ее из XML sitemap. Это безопаснее, чем вручную править генерацию.

ПодходКогда подходитМинус
Настройка в SEO-плагинеНужно исключить одну-две страницы без разработкиЗависит от интерфейса плагина
Фильтр WordPressНужна точечная логика по ID, slug или типу записиНужно поддерживать код
Отключение типа записи из sitemapВ sitemap не должен попадать целый тип контентаМожно случайно скрыть полезные страницы

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

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

  1. Определите, какой именно sitemap отдает URL: ядро WordPress или SEO-плагин.
  2. Проверьте, есть ли у страницы noindex и не закрыта ли она случайно от индексации целиком.
  3. Решите, что нужно: убрать URL только из sitemap или еще и запретить индексацию.
  4. Добавьте исключение через настройки плагина или через фильтр в functions.php дочерней темы либо в небольшом mu-plugin.
  5. Очистите кеш сайта и, если есть, кеш CDN.
  6. Переоткройте sitemap и убедитесь, что URL исчез.

Для production-сайта лучше не править functions.php основной темы. Если тема обновится, код потеряется. Практичнее вынести такую логику в mu-plugin. Это обычный PHP-файл в wp-content/mu-plugins/, который загружается автоматически.

<?php
/**
 * Plugin Name: Sitemap exclusions
 */

add_filter( 'wp_sitemaps_posts_entry', function( $entry, $post ) {
	$excluded_slugs = array( 'thank-you', 'internal-search', 'test-page' );

	if ( in_array( $post->post_name, $excluded_slugs, true ) ) {
		return false;
	}

	return $entry;
}, 10, 2 );

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

Проверка должна быть не на глаз, а по нескольким признакам. Сначала откройте сам sitemap и убедитесь, что URL исчез. Затем проверьте страницу в браузере без авторизации: карта сайта должна отдаваться без ошибок, а XML — быть валидным. После этого посмотрите в Search Console, если сайт уже там подключен: URL не должен продолжать активно попадать в отчет по sitemap после следующего обхода.

  • URL отсутствует в XML sitemap;
  • страница не получает новые переходы из карты сайта в аналитике;
  • в коде страницы стоит ожидаемый noindex, если вы его добавляли;
  • кеш очищен, и старая версия sitemap не отдается из CDN или плагина кеша.

Если URL все еще виден, проверьте три вещи: не генерируется ли sitemap вторым плагином, не закеширован ли XML на уровне сервера, и не осталась ли старая версия в объектном кеше. На сайтах с агрессивным кешированием это частая причина ложного ощущения, что код не работает.

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

Удалили страницу из меню, но она осталась в sitemap

Меню не влияет на XML sitemap. Поисковик не ориентируется на навигацию сайта как на список разрешенных URL. Нужно менять именно генерацию карты сайта или настройки SEO-плагина.

Поставили noindex, но URL все равно в карте сайта

Это нормальная ситуация для части конфигураций. noindex запрещает индексацию, но не всегда убирает URL из sitemap автоматически. Если цель — не светить страницу в карте сайта, добавьте отдельное исключение.

Сломали sitemap после правки functions.php

Часто причина в синтаксической ошибке или в конфликте с темой. Если сайт начал отдавать 500 ошибку, уберите код через FTP или файловый менеджер хостинга и перенесите логику в mu-plugin. Это проще откатить и безопаснее для обновлений.

Исключили не тот тип записей

Если фильтр написан слишком широко, можно случайно убрать из sitemap целый раздел сайта. Перед выкладкой проверьте условие: тип записи, slug, метаполя и список ID. На больших сайтах лучше сначала протестировать на staging-копии.

Что делать с безопасностью и производительностью

Любая правка sitemap должна быть минимальной. Не добавляйте тяжелые запросы к базе в фильтры генерации, иначе карта сайта станет медленной. Если у вас десятки тысяч записей, лишний проход по метаданным на каждом запросе sitemap быстро станет заметен. Для таких задач лучше опираться на slug, ID или заранее сохраненный флаг в post meta.

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

Практический ориентир простой: если страница не должна индексироваться, она не должна одновременно быть в меню, в sitemap и во внутренней перелинковке. Иначе вы получите противоречивые сигналы для поисковика и лишнюю работу на поддержке.