Ситуация типовая: на сайте есть страницы, которые должны открываться по прямой ссылке, но не должны попадать в поиск, архивы и внутреннюю навигацию. Это могут быть страницы благодарности, результаты фильтров, служебные разделы, черновые лендинги, страницы с дублирующим контентом или технические URL после миграции.
Если просто поставить noindex в SEO-плагине, этого иногда достаточно. Но на практике часто нужно решить сразу несколько задач: убрать страницу из выдачи, не показывать её в списках, не отдавать в XML-карту сайта и не ломать прямой доступ для пользователей или интеграций. Ниже — рабочий вариант без выдуманных хуков и без лишней магии.
Когда проблема действительно в индексации, а не в шаблоне
Перед правкой кода стоит понять, что именно не так. Иногда страница видна в поиске, потому что она реально индексируется. Иногда она не должна индексироваться, но продолжает всплывать в блоках «Похожие записи», в хлебных крошках, в sitemap или в результатах внутреннего поиска WordPress.
Что проверить в первую очередь
- Есть ли у страницы статус
publishи доступна ли она по прямому URL. - Есть ли на ней мета-тег
noindexв исходном коде. - Попадает ли URL в XML-карту сайта.
- Показывается ли страница в результатах внутреннего поиска WordPress.
- Не выводится ли она в списках через
WP_Queryили виджеты.
Если страница уже удалена, но продолжает светиться в поиске, это другая задача: там нужен редирект или корректная отдача 404/410. Если страница нужна для пользователей, но не для поисковиков, тогда подходит сценарий с исключением из индексации.
Какие есть варианты: плагин, код или оба сразу
Для большинства сайтов удобнее всего управлять индексацией через SEO-плагин. Но если задача точечная и касается только нескольких URL, код часто проще и прозрачнее. Особенно если нужно исключать страницы по шаблону, по slug или по типу записи.
| Подход | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
| SEO-плагин | Нужно быстро закрыть страницу от индексации без разработки | Просто, видно в админке, меньше риска ошибиться | Не всегда удобно для массовых правил и нестандартной логики |
| Код в теме или мини-плагине | Нужно исключать страницы по правилам | Гибко, можно контролировать sitemap и поиск | Нужна аккуратность и тестирование |
| Плагин + код | Есть SEO-плагин, но нужны точечные исключения | Удобно поддерживать, меньше ручной рутины | Важно не дублировать правила в двух местах |
Пошаговое решение через код
Ниже пример для случая, когда нужно исключить из внутреннего поиска WordPress конкретные страницы по ID. Это безопаснее, чем пытаться править шаблон поиска вручную, и не влияет на прямой доступ по URL.
add_action('pre_get_posts', function (WP_Query $query) {
if (is_admin() || ! $query->is_main_query() || ! $query->is_search()) {
return;
}
$excluded_ids = array(12, 34, 56); // замените на свои ID
$query->set('post__not_in', $excluded_ids);
});Этот вариант убирает страницы из результатов поиска WordPress, но не запрещает их индексировать поисковикам, если на них есть ссылки. Чтобы закрыть страницу от индексации, добавьте мета-тег noindex для нужных URL.
add_action('wp_head', function () {
if (! is_page(array(12, 34, 56))) {
return;
}
echo "<meta name=\"robots\" content=\"noindex, nofollow\" />\n";
}, 1);Если у вас уже стоит SEO-плагин, проверьте, не добавляет ли он свой robots meta tag. Два разных тега с разными директивами — частая причина путаницы. В таком случае лучше оставить один источник правды.
Как исключить страницу из XML sitemap
Если карта сайта генерируется кодом или через SEO-плагин, страницу нужно убрать и оттуда. В чистом WordPress это обычно делается через фильтр wp_sitemaps_posts_query_args. Он позволяет исключить конкретные записи из sitemap для постов и страниц.
add_filter('wp_sitemaps_posts_query_args', function (array $args, string $post_type) {
if ($post_type !== 'page') {
return $args;
}
$args['post__not_in'] = array(12, 34, 56);
return $args;
}, 10, 2);Если у вас отключены встроенные карты сайта WordPress и используется SEO-плагин, этот фильтр может не сработать. Тогда нужно искать настройки конкретного плагина или его фильтры. В статье важно не смешивать оба механизма в одну кучу.
Если нужно исключать страницы по правилу, а не по ID
На живом сайте ID неудобны: они меняются при переносах, а список служебных страниц может расти. В таких случаях лучше ориентироваться на slug или шаблон страницы. Например, можно скрывать из поиска все страницы с префиксом thank-you или lp-.
add_action('pre_get_posts', function (WP_Query $query) {
if (is_admin() || ! $query->is_main_query() || ! $query->is_search()) {
return;
}
$query->set('post_type', array('post', 'page'));
$excluded_slugs = array('thank-you', 'lp-test', 'internal-docs');
$query->set('post__not_in', get_posts(array(
'post_type' => 'page',
'post_status' => 'publish',
'fields' => 'ids',
'posts_per_page' => -1,
'post_name__in' => $excluded_slugs,
)));
});Здесь есть важный нюанс: post_name__in работает в WP_Query, но для получения ID страниц по slug лучше использовать отдельный запрос через get_page_by_path() или заранее хранить список ID. Если список маленький, проще и надежнее явно указать ID.
Проверка результата после внедрения
После правок не стоит ограничиваться визуальной проверкой в браузере. Нужно проверить три вещи: поиск, исходный код страницы и sitemap.
- Откройте внутренний поиск WordPress и убедитесь, что страница не попадает в выдачу.
- Посмотрите исходный код страницы и найдите
meta name="robots". - Проверьте XML sitemap: URL не должен там присутствовать.
- Если страница уже была в индексе, отправьте её на переобход в Google Search Console или аналогичном инструменте.
Для быстрой проверки можно использовать curl и посмотреть заголовки и HTML:
curl -I https://example.com/thank-you/
curl -s https://example.com/thank-you/ | grep -i robotsЕсли страница должна быть закрыта от индексации, но всё ещё видна в поиске, это не всегда ошибка кода. Поисковику нужно время, чтобы переобойти URL и обновить индекс. Если же в исходнике нет noindex, значит правило не сработало или его перебил другой плагин.
Частые ошибки и как их исправить
Страница скрыта из поиска, но всё равно есть в sitemap
Обычно это означает, что вы исключили её только из WP_Query, но не из генератора карты сайта. Проверьте отдельную логику sitemap или настройки SEO-плагина.
Добавили noindex, но страница всё равно ранжируется
Чаще всего поисковик ещё не переобошёл страницу. Иногда проблема в том, что на URL ведут внешние ссылки, а сам тег был добавлен недавно. Если нужно убрать страницу быстро, используйте корректный редирект или отдачу 410 Gone, но только если страница действительно больше не нужна.
Сломался поиск в админке
Такое бывает, если в pre_get_posts не проверили is_admin() или не ограничили код главным запросом. Всегда ставьте защиту:
if (is_admin() || ! $query->is_main_query()) {
return;
}Два SEO-плагина одновременно управляют robots
Это плохая идея. Один плагин может ставить noindex, другой — переопределять canonical или sitemap. В итоге поведение становится непредсказуемым. Оставьте один инструмент для мета-данных и индексации.
Практические советы по безопасности и производительности
Если исключений много, не разбрасывайте их по functions.php. Лучше вынести правила в небольшой mu-plugin или отдельный мини-плагин. Так они не потеряются при смене темы и не будут зависеть от шаблона.
Ещё один практический момент: не добавляйте лишнюю логику в каждый запрос. Если список исключаемых страниц фиксированный, храните его в массиве и не делайте тяжелых запросов к базе внутри pre_get_posts. Для больших проектов это заметно лучше, чем собирать ID на лету.
Если на сайте уже есть SEO-плагин, сначала проверьте его возможности. Иногда достаточно одной настройки «не индексировать» и исключения из sitemap. Код нужен тогда, когда правило должно работать автоматически: например, для всех страниц с определённым шаблоном или префиксом slug.
Когда задача выходит за рамки одной страницы и нужно системно чистить сайт от дублей, служебных URL и мусорных архивов, удобнее держать под рукой инструмент вроде Clearfy Pro, но только если он реально закрывает вашу задачу и не конфликтует с текущим SEO-стеком.
Короткий чек-лист перед публикацией
- Проверен список страниц, которые нужно скрыть.
- Добавлен
noindexтолько на нужные URL. - Страницы исключены из внутреннего поиска WordPress.
- URL убраны из XML sitemap.
- Код не влияет на админку и главный запрос сайта.
- После правок проверен исходный код и sitemap.
Если нужен именно точечный сценарий без плагинов, такой подход обычно проще поддерживать, чем пытаться вручную править шаблоны и надеяться, что служебные страницы не всплывут в индексе снова.