На WordPress дубли часто появляются не из-за контента, а из-за параметров в URL: ?utm_source=, ?gclid=, ?fbclid=, а иногда и из-за внутренних служебных параметров плагинов. Для пользователя это одна и та же страница, а для поисковика — несколько разных адресов. В итоге в индексе копятся мусорные URL, а каноникал начинает работать не так предсказуемо, как хотелось бы.
Задача здесь не в том, чтобы «запретить всё подряд». Нормальная схема выглядит иначе: оставить рабочие параметры для аналитики и рекламы, но не давать им плодить отдельные индексируемые страницы. Ниже — как это проверить, чем закрывать и где чаще всего ошибаются.
Когда проблема уже есть и как её распознать
Первый признак — в поиске или в отчётах краулинга появляются одинаковые страницы с разными параметрами. Второй — в Google Search Console в отчёте по страницам видно много URL с ?, хотя контент у них тот же. Третий — в логах или в аналитике встречаются переходы на адреса вида /article/?utm_source=telegram, а в индексе почему-то живёт именно этот вариант.
Проверить это можно быстро:
- выполнить поиск по сайту с параметром, например
site:example.com inurl:utm_; - посмотреть, какой
rel=canonicalотдаёт страница с параметром; - сравнить HTTP-ответ для чистого URL и URL с параметром;
- проверить, не создаёт ли плагин отдельные страницы на основе query string.
Что считать нормой, а что — дублем
Если параметр нужен только для трекинга и не меняет содержимое страницы, это почти всегда дубль. Если параметр реально меняет выдачу — например, сортировку, фильтр или язык интерфейса — тогда решение уже другое: иногда нужен canonical на базовую страницу, иногда noindex, а иногда параметр вообще нельзя резать без теста.
| Подход | Когда подходит | Минус |
|---|---|---|
| Canonical на чистый URL | Параметр не меняет контент | Не убирает URL из логов и переходов |
| Noindex для параметризованных URL | Нужно исключить из индекса, но оставить доступ | Требует аккуратной настройки, чтобы не задеть нужные страницы |
| Редирект 301 на чистый URL | Параметр не нужен вообще | Можно потерять данные трекинга, если делать бездумно |
Пошаговое решение: как убрать дубли и не сломать аналитику
Самый безопасный путь — не редиректить все параметры подряд, а сначала определить список служебных query string, которые не должны индексироваться. Для типичного сайта это utm_*, gclid, fbclid, yclid, иногда _ga и параметры, которые добавляют рекламные или аналитические системы.
Если у вас уже есть SEO-плагин, проверьте, умеет ли он ставить canonical на базовый URL для страниц с параметрами. Если нет — можно добавить это кодом. Ниже пример для functions.php дочерней темы или небольшого mu-plugin.
<?php
add_filter('get_canonical_url', function ($canonical, $post) {
if (is_admin() || ! is_singular() || empty($_SERVER['REQUEST_URI'])) {
return $canonical;
}
$uri = wp_unslash($_SERVER['REQUEST_URI']);
$parts = wp_parse_url(home_url($uri));
if (empty($parts['query'])) {
return $canonical;
}
parse_str($parts['query'], $query);
$tracked_keys = array('gclid', 'fbclid', 'yclid');
foreach ($query as $key => $value) {
if (strpos($key, 'utm_') === 0 || in_array($key, $tracked_keys, true)) {
unset($query[$key]);
}
}
if (empty($query)) {
return get_permalink($post);
}
return add_query_arg($query, get_permalink($post));
}, 10, 2);Этот код не трогает все URL подряд. Он лишь приводит canonical к чистому адресу, если в URL есть только трекинговые параметры. Если в query string остались рабочие параметры, они сохраняются.
Если нужно жёстче закрыть именно индексацию параметризованных URL, можно добавить noindex,follow для таких страниц. Делать это стоит только после проверки, что параметр не нужен для отдельного контента.
<?php
add_filter('wp_robots', function ($robots) {
if (is_admin() || empty($_SERVER['REQUEST_URI'])) {
return $robots;
}
$uri = wp_unslash($_SERVER['REQUEST_URI']);
$query = wp_parse_url(home_url($uri), PHP_URL_QUERY);
if (! $query) {
return $robots;
}
parse_str($query, $params);
foreach ($params as $key => $value) {
if (strpos($key, 'utm_') === 0 || in_array($key, array('gclid', 'fbclid', 'yclid'), true)) {
$robots['noindex'] = true;
$robots['follow'] = true;
break;
}
}
return $robots;
});Когда нужен редирект, а когда нет
Редирект 301 имеет смысл только если параметр не нужен вообще и не используется в отчётах, которые вы реально смотрите. Например, если кто-то вручную добавил ?ref= к внутренним ссылкам, а это не часть логики сайта, такой параметр можно убрать редиректом на чистый URL. Но для UTM и рекламных меток редирект часто вреден: он ломает атрибуцию перехода и делает аналитику менее точной.
Если сомневаетесь, лучше оставить параметр в адресе для пользователя, но закрыть его от индекса через canonical или noindex. Это обычно безопаснее, чем массовый 301.
Как проверить, что решение сработало
После правки не ограничивайтесь визуальной проверкой страницы. Нужно посмотреть именно технические признаки.
- Откройте URL с параметром и проверьте исходный код: canonical должен вести на чистую страницу.
- Проверьте мета robots: для служебных параметров должен быть
noindex,follow, если вы его включали. - Сравните ответ сервера для чистого URL и URL с параметром через
curl -Iили DevTools. - Убедитесь, что страница с параметром не попадает в sitemap.
- Через несколько обходов поисковика проверьте, что в отчётах Search Console уменьшается число URL с query string.
Пример быстрой проверки через командную строку:
curl -sL 'https://example.com/article/?utm_source=test' | grep -i canonical
curl -sL 'https://example.com/article/?utm_source=test' | grep -i 'robots'Если canonical всё ещё указывает на URL с параметром, значит фильтр не сработал или его перебивает SEO-плагин. Тогда нужно смотреть приоритеты хуков и порядок загрузки.
Частые ошибки и как их исправить
Ставят 301 на все query string
Это самая грубая ошибка. Внешние кампании, рекламные клики и часть интеграций перестают нормально атрибутироваться. Исправление простое: редиректить только те параметры, которые точно не нужны, а UTM и рекламные метки оставлять без редиректа.
Закрывают noindex вместе с canonical на разные URL
Если canonical указывает на одну страницу, а noindex стоит на другой логике, поисковик получает противоречивые сигналы. В результате страница может индексироваться дольше, чем ожидалось, или игнорировать canonical. Лучше выбрать один основной сценарий: либо canonical на чистый URL, либо noindex для параметризованных версий.
Забывают про внутренние ссылки
Если сайт сам генерирует ссылки с UTM или служебными параметрами, внешняя настройка не спасёт. Нужно найти источник: шаблон темы, блок, виджет, кнопку в плагине, автодобавление меток в маркетинговом модуле. Иначе дубли будут появляться снова.
Проверяют только главную страницу
На практике проблема чаще сидит в карточках, статьях, тегах и страницах архивов. Проверяйте несколько типов URL, а не один. Особенно если на сайте есть фильтры, поиск по сайту или рекламные посадочные.
Практические советы по безопасности и производительности
Не стоит вешать тяжёлую логику на каждый запрос без необходимости. Если вы пишете свой код, ограничьте его страницами, где реально встречаются параметры, и не делайте лишних обращений к базе. Для большинства задач достаточно работы с $_SERVER['REQUEST_URI'] и стандартных функций WordPress.
Если у вас большой сайт и много технических правил, удобнее вынести такие настройки в отдельный mu-plugin, а не в тему. Тогда они не пропадут при смене шаблона. Ещё один практичный момент: перед массовыми изменениями проверьте, не использует ли рекламная команда отчёты по UTM в текущем виде. Иногда лучше сначала внедрить canonical и noindex, а редиректы отложить до анализа данных.
Если нужен более широкий набор инструментов для чистки дублей и технической оптимизации, можно посмотреть на Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но даже с плагином полезно понимать, какие именно параметры вы закрываете и почему.
Мини-чек-лист перед выкладкой на прод
- Проверен список параметров, которые реально нужны аналитике.
- Canonical на URL с параметрами ведёт на чистую страницу.
- Noindex не включён на страницах, где параметр меняет контент.
- Внутренние ссылки не генерируют лишние query string.
- Страницы с параметрами не попадают в sitemap.
- После публикации сделана проверка через браузер, curl и Search Console.
Если после внедрения в индексе всё ещё остаются старые URL, это не всегда ошибка настройки. Поисковику нужно время, чтобы переобойти страницы и переоценить сигналы. Но если canonical, robots и внутренняя перелинковка уже приведены в порядок, обычно проблема перестаёт расти дальше.