Страницы с GET-параметрами — типичная причина дублей в WordPress. На одном и том же контенте появляются разные URL: ?sort=price, ?filter=color, ?s=, ?replytocom=. Для пользователя это иногда полезно, а для поисковика — часто лишний шум. Ошибка здесь не в самих параметрах, а в том, что сайт начинает отдавать десятки почти одинаковых страниц без понятной индексационной логики.
Ниже разберём, что именно закрывать от индексации, как это сделать на уровне WordPress, где помогает noindex, а где лучше ограничиться canonical или вообще не трогать URL. Примеры подойдут для темы, плагина или небольшого mu-plugin.
Когда проблема действительно есть
Сначала стоит убедиться, что у вас не просто «страшные URL», а реальная индексационная проблема. Если в поиске появляются страницы с параметрами, а в отчётах по обходу растёт число дублей, это уже повод вмешаться.
Признаки, которые можно проверить руками
- в поиске находятся URL вида
/catalog/?sort=priceили/blog/?s=wordpress; - одна и та же страница доступна по нескольким адресам с разными параметрами;
- в HTML у параметризованных страниц нет явного
canonicalна чистый URL; - в
robots.txtзакрыт только обход, но страницы уже успели попасть в индекс; - поисковик тратит краулинговый бюджет на сортировки, фильтры и внутренний поиск.
Отдельно проверьте, не закрываете ли вы случайно полезные страницы. Например, параметры пагинации или сортировки иногда нужны для пользователей, но не должны индексироваться как самостоятельные документы.
Что закрывать, а что оставлять
Не все параметры одинаково вредны. Если закрыть всё подряд, можно потерять полезные посадочные страницы. Если не закрыть ничего, индекс быстро забивается дублями.
| Сценарий | Что делать | Почему |
|---|---|---|
Внутренний поиск ?s= | noindex, follow и canonical на базовую страницу поиска или на саму страницу поиска без запроса | Результаты поиска редко должны быть отдельными посадочными страницами |
Сортировка ?sort= | обычно canonical на чистый URL, иногда noindex | Контент тот же, меняется только порядок |
Фильтры каталога ?filter= | зависит от стратегии: часть страниц можно оставить, часть закрыть | Некоторые комбинации могут быть полезными посадочными |
Технические параметры ?replytocom=, UTM, служебные хвосты | закрывать от индексации и нормализовать canonical | Это почти всегда дубль |
Если у вас уже есть SEO-плагин, сначала проверьте его настройки. Иногда достаточно включить корректный canonical и запретить индексацию страниц поиска. Но если нужна точечная логика по параметрам, удобнее добавить код.
Пошаговое решение через WordPress
Ниже — рабочий вариант для темы или небольшого плагина. Он добавляет noindex,follow для страниц с нежелательными параметрами и ставит canonical на чистый URL. Это не заменяет нормальную архитектуру фильтров, но помогает быстро убрать мусор из индекса.
1. Добавьте проверку параметров
<?php
add_action('wp_head', function () {
if (is_admin()) {
return;
}
$blocked_params = array('sort', 'filter', 'replytocom');
$has_blocked_param = false;
foreach ($blocked_params as $param) {
if (isset($_GET[$param]) && $_GET[$param] !== '') {
$has_blocked_param = true;
break;
}
}
if (!$has_blocked_param) {
return;
}
echo '<meta name="robots" content="noindex,follow" />' . "\n";
}, 1);Этот код не ломает загрузку страницы и работает только на фронтенде. Но одного noindex мало: поисковику нужно показать, какая версия страницы основная.
2. Добавьте canonical на чистый URL
<?php
add_filter('wpseo_canonical', function ($canonical) {
if (is_admin()) {
return $canonical;
}
$blocked_params = array('sort', 'filter', 'replytocom');
foreach ($blocked_params as $param) {
if (isset($_GET[$param]) && $_GET[$param] !== '') {
return remove_query_arg($blocked_params, home_url(add_query_arg(array(), $GLOBALS['wp']->request)));
}
}
return $canonical;
});Этот пример рассчитан на сайты, где используется Yoast SEO, потому что фильтр wpseo_canonical относится именно к нему. Если у вас другой SEO-плагин, логика та же, но хук будет другим. Если SEO-плагина нет, canonical можно вывести через wp_head вручную.
Для ручного варианта лучше не собирать URL через сложные конструкции, а использовать текущий адрес без параметров:
<?php
add_action('wp_head', function () {
if (is_admin()) {
return;
}
if (empty($_GET)) {
return;
}
$blocked_params = array('sort', 'filter', 'replytocom');
$has_blocked_param = false;
foreach ($blocked_params as $param) {
if (isset($_GET[$param]) && $_GET[$param] !== '') {
$has_blocked_param = true;
break;
}
}
if (!$has_blocked_param) {
return;
}
$canonical = remove_query_arg(array_keys($_GET), home_url(add_query_arg(array(), $GLOBALS['wp']->request)));
echo '<link rel="canonical" href="' . esc_url($canonical) . '" />' . "\n";
}, 5);3. Закройте служебные параметры в robots.txt только как дополнительный слой
robots.txt не удаляет URL из индекса, если он уже туда попал. Поэтому использовать его стоит как вспомогательную меру, а не как единственный способ.
User-agent: *
Disallow: /*?replytocom=
Disallow: /*?sort=
Disallow: /*?filter=
Disallow: /?s=Такой файл помогает уменьшить лишний обход, но не решает вопрос canonical и мета-роботов. Если страница уже в индексе, одного Disallow обычно недостаточно.
Если нужен более точный контроль
Иногда закрывать нужно не все параметры, а только отдельные комбинации. Например, фильтр по цвету и размеру может быть бесполезен для индекса, а фильтр по категории и типу материала — полезен как посадочная страница. В этом случае лучше строить правила по whitelist, а не по blacklist.
Пример логики whitelist
<?php
function mentor_should_noindex_query() {
$allowed = array('category', 'material');
$params = array_keys($_GET);
if (empty($params)) {
return false;
}
foreach ($params as $param) {
if (!in_array($param, $allowed, true)) {
return true;
}
}
return false;
}
add_action('wp_head', function () {
if (is_admin() || !mentor_should_noindex_query()) {
return;
}
echo '<meta name="robots" content="noindex,follow" />' . "\n";
}, 1);Такой подход удобен, если у вас есть SEO-логика для фильтров и вы не хотите случайно закрыть полезные страницы. Но перед внедрением whitelist нужно составить список параметров, которые реально должны индексироваться.
Как проверить, что решение сработало
Проверка нужна не только в коде, но и в браузере, и в поисковой системе. Иначе можно долго думать, что всё исправлено, а на деле canonical не выводится или конфликтует с плагином.
- Откройте страницу с параметром, например
?sort=price, и посмотрите исходный код. - Убедитесь, что есть
<meta name="robots" content="noindex,follow" />. - Проверьте, что canonical указывает на чистый URL без параметров.
- В Search Console отправьте URL на проверку и посмотрите, как он интерпретируется после повторного обхода.
- Сравните несколько параметров: один должен закрываться, другой — нет, если вы используете whitelist.
Если сайт кэшируется на уровне плагина или сервера, не забудьте очистить кэш после изменений. Иначе в исходнике вы увидите старую версию страницы, а не результат правки.
Частые ошибки и как их исправить
Закрыли URL в robots.txt и забыли про canonical
Это самая частая ошибка. Поисковик перестаёт обходить страницу, но уже известный URL может продолжать жить в индексе. Исправление: снять лишний Disallow, добавить noindex и canonical, затем дождаться повторного обхода.
Ставят noindex на все страницы с параметрами
Так можно случайно закрыть полезные посадочные страницы. Исправление: перейти на whitelist или хотя бы разделить параметры на служебные и контентные.
Конфликт с SEO-плагином
Если Yoast SEO, Rank Math или другой плагин уже выводит canonical, ваш ручной код может создать дубль тега. Исправление: оставьте только один источник canonical. Либо используйте фильтр плагина, либо полностью управляйте тегом из темы/плагина.
Кэш не обновили после правки
На сайтах с page cache и CDN это выглядит как «код не работает». Исправление: очистить кэш плагина, серверный кэш и, если нужно, CDN.
Используют noindex для страниц, которые должны ранжироваться
Иногда параметры — это не мусор, а часть SEO-структуры. Например, отдельные страницы фильтров под спрос. Исправление: пересмотреть карту индексации и убрать запрет только с тех URL, которые реально нужны в поиске.
Что делать для безопасности и производительности
Когда вы работаете с параметрами из $_GET, не выводите их в HTML без экранирования. Даже если параметр кажется «внутренним», его может подставить кто угодно. Для canonical используйте esc_url(), для текста — соответствующие функции экранирования WordPress.
С точки зрения производительности лучше не строить сложную логику на каждом запросе. Если список параметров фиксированный, держите его в простом массиве и не подключайте тяжёлые проверки. Для больших сайтов с фильтрами разумнее вынести нормализацию URL в отдельный плагин или использовать возможности SEO-модуля, если он уже есть.
Если вам нужен более системный контроль дублей, иногда удобнее не писать всё вручную, а использовать плагин для технической очистки сайта. Например, в Clearfy Pro есть инструменты для работы с дублями и служебными элементами SEO, но даже в этом случае логику параметров лучше проверить на тестовой копии сайта перед включением на проде: Clearfy Pro.
Если после внедрения страницы с параметрами всё ещё попадают в индекс, проверьте три вещи: нет ли внешних ссылок на такие URL, не генерирует ли их тема или плагин автоматически, и не возвращает ли сервер редирект на канонический адрес только для части запросов. В технической SEO-работе именно такие несостыковки чаще всего и создают проблему.