Проблема с параметрами в URL обычно выглядит одинаково: сайт начинает плодить десятки и сотни адресов вида ?sort=, ?filter=, ?page=, ?utm_, а в индекс попадают не те страницы, которые вы хотите продвигать. Для WordPress это особенно заметно на каталогах, подборках, поиске по сайту, страницах с фильтрами и сортировками. Если не разрулить это заранее, поисковик тратит обход на мусорные комбинации, а в отчётах появляются дубли и странные каноникалы.
Когда проблема уже есть: как понять, что индекс расползается
Сначала стоит не править вслепую, а проверить симптомы. Самый простой способ — посмотреть, какие URL реально индексируются и какие параметры в них встречаются. В Google Search Console откройте отчёт по страницам и выгрузите список URL с параметрами. В Яндекс Вебмастере полезно смотреть обход и страницы в поиске, если у вас есть доступ к этим данным.
Типичные признаки:
- в выдаче появляются адреса с сортировкой, пагинацией или фильтрами;
- в логах много запросов к однотипным URL с разными параметрами;
- канонический URL у параметрических страниц указывает на саму себя или на случайную вариацию;
- в sitemap попадают страницы, которые не должны индексироваться;
- внутренние ссылки ведут на URL с UTM-метками или служебными параметрами.
Что именно искать в коде и в базе
Если сайт собран на шаблоне или плагинах фильтрации, проверьте, не генерируются ли ссылки с параметрами прямо в шаблонах. Иногда проблема не в поисковике, а в том, что тема отдаёт в меню, хлебных крошках или блоках похожих материалов URL с лишними query string. Это уже не вопрос robots.txt, а вопрос качества ссылок на сайте.
// Пример: вывод URL с параметром, который лучше не использовать в внутренних ссылках
$link = add_query_arg( array( 'sort' => 'price' ), get_permalink( $post_id ) );
echo esc_url( $link );
Сам по себе такой URL не ошибка, если он нужен пользователю. Ошибка начинается тогда, когда он становится основным внутренним адресом и начинает индексироваться как отдельная страница.
Что закрывать, а что оставлять: короткая логика без лишней магии
Не все параметры одинаково вредны. UTM-метки, параметры сортировки, технические флаги и служебные идентификаторы обычно не должны становиться отдельными страницами. А вот фильтры, которые формируют действительно полезные посадочные страницы, иногда лучше оставить открытыми и дать им нормальные заголовки, описание и каноникал.
| Подход | Когда уместен | Плюсы | Минусы |
|---|---|---|---|
| Плагин для SEO/чистки | Когда нужно быстро закрыть часть дублей без доработки темы | Меньше ручного кода, проще поддержка | Не всегда покрывает нестандартные фильтры |
| Код в теме или mu-plugin | Когда параметры известны и логика сайта стабильна | Точный контроль, нет лишних зависимостей | Нужна аккуратная поддержка при обновлениях |
| Только robots.txt | Когда нужно снизить обход, но не решать канонизацию | Быстро | Не убирает уже найденные URL из индекса |
Если задача именно в индексации, одного robots.txt обычно мало. Он может ограничить обход, но не гарантирует удаление уже известных адресов из индекса. Поэтому рабочая схема почти всегда состоит из двух частей: правильные мета-указания для страниц и контроль ссылок/каноникалов.
Пошаговое решение: закрываем служебные параметры и не ломаем полезные страницы
Ниже — практичный вариант для WordPress, когда нужно убрать из индекса URL с параметрами sort, filter, utm_* и похожими служебными значениями. Логику можно адаптировать под свой проект.
Шаг 1. Отдаём noindex для параметрических страниц
Если у вас есть доступ к теме или небольшому mu-plugin, можно добавить проверку query string и выставлять noindex,follow только для технических параметров. Это безопаснее, чем массово закрывать всё подряд.
<?php
add_action( 'wp_head', function () {
if ( is_admin() ) {
return;
}
$params = array_keys( $_GET );
if ( empty( $params ) ) {
return;
}
$technical_params = array( 'sort', 'filter', 'orderby', 'page', 'utm_source', 'utm_medium', 'utm_campaign' );
$matched = array_intersect( $params, $technical_params );
if ( empty( $matched ) ) {
return;
}
echo '<meta name="robots" content="noindex,follow" />' . "\n";
}, 1 );
Этот пример не пытается быть универсальным для всех сайтов. Он показывает принцип: если на странице есть только служебные параметры, поисковику лучше не давать её как отдельную посадочную.
Шаг 2. Добавляем canonical на чистый URL
Даже если страница получает noindex, полезно указывать канонический адрес без параметров. Это помогает поисковику связать вариации с основной страницей.
<?php
add_filter( 'get_canonical_url', function ( $canonical, $post ) {
if ( is_admin() || empty( $_GET ) ) {
return $canonical;
}
$technical_params = array( 'sort', 'filter', 'orderby', 'utm_source', 'utm_medium', 'utm_campaign' );
$params = array_keys( $_GET );
$matched = array_intersect( $params, $technical_params );
if ( empty( $matched ) ) {
return $canonical;
}
return get_permalink( $post );
}, 10, 2 );
Если у вас не одиночная запись, а архив или страница каталога, логику нужно адаптировать под тип страницы. Важно не подменять canonical на случайный URL, а приводить его к чистому основному адресу.
Шаг 3. Не пускаем мусорные параметры в внутренние ссылки
Частая ошибка — закрыть страницы от индексации, но оставить в меню, блоках и карточках ссылки с параметрами. Тогда бот всё равно будет их находить, а пользователи будут получать нестабильные адреса. Если параметр нужен только для интерфейса, генерируйте его на фронтенде или храните состояние без изменения URL.
<?php
function yelly_clean_internal_url( $url ) {
$allowed = array( 'post_type', 's', 'paged' );
$parts = wp_parse_url( $url );
if ( empty( $parts['query'] ) ) {
return $url;
}
parse_str( $parts['query'], $query );
$query = array_intersect_key( $query, array_flip( $allowed ) );
$base = isset( $parts['scheme'] ) ? $parts['scheme'] . '://' : '';
$base .= isset( $parts['host'] ) ? $parts['host'] : '';
$base .= isset( $parts['path'] ) ? $parts['path'] : '';
return $query ? add_query_arg( $query, $base ) : $base;
}
Это не готовый универсальный фильтр для всего сайта, а рабочая заготовка, которую можно встроить в генерацию ссылок там, где у вас действительно есть риск раздавать лишние параметры.
Если нужен быстрый вариант без кода
Когда проект небольшой или доступ к теме ограничен, проще начать с SEO-плагина и точечной настройки. Например, в Clearfy Pro есть инструменты для чистки сайта и управления техническими дублями; это уместно, если вам нужно быстро убрать часть мусорных страниц без ручной правки шаблонов. Но даже в таком случае всё равно проверьте, как плагин влияет на canonical, robots и внутренние ссылки. Автоматическая настройка не всегда совпадает с логикой конкретного проекта.
Если вы идёте через плагин, проверьте три вещи:
- можно ли исключить только служебные параметры, а не весь архив или весь тип записей;
- не ломается ли пагинация;
- не исчезают ли из индекса полезные посадочные страницы, которые должны ранжироваться.
Как проверить, что решение сработало
Проверка нужна не только в исходном коде, но и в ответе сервера и в индексации. Сначала откройте несколько URL с параметрами и посмотрите исходный HTML. В нём должен быть noindex,follow для технических страниц и canonical на чистый адрес. Затем проверьте, не отдаёт ли страница статус 200 там, где вы ожидали редирект, и наоборот.
- Откройте URL с
?utm_source=testи убедитесь, что в<head>есть нужный robots-мета-тег. - Проверьте canonical через просмотр исходника или инструменты браузера.
- Сравните URL в Search Console до и после переобхода.
- Посмотрите серверные логи: бот должен реже ходить по мусорным комбинациям.
- Проверьте sitemap — туда не должны попадать параметрические адреса.
Если страница всё ещё индексируется, не делайте вывод по одному дню. Поисковику нужно время на переобход и переоценку сигналов. Но если canonical и robots настроены правильно, а внутренние ссылки чистые, динамика обычно меняется в нужную сторону.
Частые ошибки и как их исправить
Закрыли всё через robots.txt
Это частая ловушка. Robots.txt может ограничить обход, но не решает вопрос уже известных URL. Если страница уже в индексе, одного запрета на crawl мало. Нужны canonical, noindex и нормализация внутренних ссылок.
Поставили noindex на полезные фильтры
Не каждый фильтр — мусор. Если фильтр создаёт реально востребованную посадочную страницу, её можно оставить открытой и доработать как отдельный URL. Ошибка здесь в том, что технический подход применяют к контентной странице.
Оставили UTM в меню и хлебных крошках
UTM-метки нужны для аналитики, а не для внутренних переходов. Если они попадают в навигацию, это почти всегда баг генерации ссылок. Исправление простое: чистить URL перед выводом и не хранить метки в постоянных ссылках.
Сломали пагинацию
Иногда разработчики ставят правила слишком грубо и закрывают ?paged= вместе с важными архивами. В результате поисковик перестаёт нормально обходить страницы списка. Если пагинация нужна, не надо закрывать её целиком — лучше контролировать canonical и следить, чтобы не индексировались только технические комбинации.
Безопасность и производительность: что не стоит делать
Не добавляйте в тему тяжёлые проверки на каждый запрос, если можно решить задачу на уровне одного фильтра или небольшого mu-plugin. Не используйте регулярки на весь $_SERVER['REQUEST_URI'] без необходимости: на больших сайтах это превращается в лишнюю нагрузку и усложняет отладку. И не редактируйте ядро WordPress — после обновления вы потеряете все изменения.
Если у вас много параметрических страниц, полезно ещё раз проверить кеширование. Иногда кеш хранит и чистые URL, и параметрические вариации как отдельные сущности. Это нормально только тогда, когда вариации действительно нужны. Если нет — лучше нормализовать URL до кеша, а не после.
Для проектов, где технических дублей много из-за темы, фильтров и архивов, имеет смысл вынести чистку в отдельный слой: mu-plugin, SEO-плагин или аккуратную настройку шаблонов. Так проще поддерживать логику после обновлений и не ловить регрессии при смене темы.
Если после внедрения вы видите, что поисковик всё равно индексирует мусорные URL, проверьте не только мета-теги, но и источник ссылок. В WordPress чаще всего проблема не в одном параметре, а в цепочке: шаблон генерирует ссылку, бот её находит, sitemap её подхватывает, а canonical указывает не туда. Лечить нужно всю цепочку, а не один симптом.