Если в WordPress одна и та же страница открывается с разными параметрами в URL, поисковик часто видит это как набор почти одинаковых документов. Типичный пример — ?utm_source=, ?sort=, ?replytocom=, параметры фильтров и служебные хвосты после переходов из рекламы или почты. Сам по себе параметр не всегда проблема, но без корректного canonical он легко превращается в источник дублей и размывает сигналы страницы.
Ниже разберём, когда достаточно настроить canonical, когда лучше закрывать параметризованные URL от индексации, и как проверить, что WordPress действительно отдаёт нужный адрес в <head>.
Когда canonical нужен, а когда он не решает проблему
canonical полезен, если у вас есть одна основная версия страницы, а параметры нужны только для удобства пользователя или аналитики. Например, сортировка товаров, UTM-метки, якорные переходы, переключение вида списка. В таких случаях поисковику нужно явно показать: индексировать следует базовый URL без параметров.
Но canonical не лечит всё подряд. Если параметр меняет смысл страницы и контент реально отличается, слепо указывать на базовую версию нельзя. Иначе вы сами подскажете поисковику игнорировать важную страницу.
Подходит для таких сценариев
- UTM-метки и другие маркетинговые параметры.
- Сортировка и пагинация, если они не должны ранжироваться отдельно.
- Параметры интерфейса, которые не меняют основной контент.
- Служебные хвосты вроде
?replytocom=в комментариях.
Не подходит, если параметр меняет смысл страницы
- Фильтр, который формирует отдельную посадочную страницу с уникальным спросом.
- Поисковый параметр, по которому пользователь получает другой набор материалов.
- Страницы с разным контентом, где canonical на базовую версию будет ошибкой.
Диагностика: что именно ломает индексацию
Перед правками не угадывайте. Сначала посмотрите, какие URL реально появляются в индексе и в логах обхода. Обычно проблема видна в нескольких местах: в отчёте поисковой системы, в sitemap, в шаблоне темы и в плагинах, которые добавляют свои метки к ссылкам.
Проверьте:
- есть ли в индексе URL с параметрами;
- одинаков ли
canonicalу базовой и параметризованной версии; - не генерирует ли тема лишние параметры в навигации;
- не дублируются ли страницы через HTTP/HTTPS, www/non-www, слэш на конце;
- не переписывает ли canonical SEO-плагин поверх вашей темы.
Быстрая проверка через браузер и консоль:
curl -sL 'https://example.com/page/?utm_source=test' | grep -i canonicalЕсли в ответе canonical указывает на саму параметризованную версию или вообще отсутствует, это уже рабочая зацепка. Дальше смотрите, кто именно его выводит: тема, SEO-плагин или кастомный код.
Пошаговое решение: задаём canonical для URL с параметрами
Самый надёжный вариант — не править шаблоны вручную в нескольких местах, а добавить фильтр, который будет подменять canonical только для нужных параметров. В WordPress для этого подходит wpseo_canonical, если у вас используется Yoast SEO, или собственный вывод через rel_canonical, если вы контролируете head без SEO-плагина. Ниже пример для случая, когда canonical формирует тема или стандартный WordPress-хук.
Пример: если в URL есть только маркетинговые параметры, canonical должен вести на чистую страницу без них.
<?php
add_filter( 'get_canonical_url', function( $canonical, $post ) {
if ( is_admin() || ! is_singular() ) {
return $canonical;
}
$allowed_params = array( 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content' );
$query_args = wp_unslash( $_GET );
if ( empty( $query_args ) ) {
return $canonical;
}
$has_only_tracking_params = true;
foreach ( array_keys( $query_args ) as $param ) {
if ( ! in_array( $param, $allowed_params, true ) ) {
$has_only_tracking_params = false;
break;
}
}
if ( $has_only_tracking_params ) {
return get_permalink( $post );
}
return $canonical;
}, 10, 2 );Этот вариант полезен, когда вы хотите сохранить canonical для обычных страниц, но убрать влияние UTM и похожих меток. Если у вас SEO-плагин уже выводит canonical, не дублируйте его вручную в теме — сначала отключите лишний вывод, иначе поисковик увидит два разных тега.
Если нужен canonical только для конкретных параметров
Иногда проще и безопаснее ограничить логику одним-двумя параметрами, например sort или filter. Тогда вы не трогаете остальные URL и не рискуете сломать служебные переходы.
<?php
add_filter( 'get_canonical_url', function( $canonical ) {
if ( empty( $_GET['sort'] ) ) {
return $canonical;
}
$url = remove_query_arg( array( 'sort' ) );
return $url;
} );Если параметр должен оставаться в адресной строке для пользователя, но не участвовать в canonical, этот подход работает нормально. Главное — не удалять параметры, которые реально меняют контент.
Сравнение подходов: плагин, код или ручная правка
| Подход | Когда уместен | Минус |
|---|---|---|
| SEO-плагин | Если canonical уже управляется через Yoast или аналог и нужно точечно поправить шаблон | Можно случайно получить конфликт с темой или другим SEO-модулем |
| Код в теме или mu-plugin | Когда нужен контроль над отдельными параметрами и логикой | Требует проверки после обновлений |
| Ручная правка шаблона head | Только если сайт очень простой и нет SEO-плагина | Легко забыть про часть шаблонов и получить дубли |
На практике для рабочих проектов лучше либо настраивать canonical через SEO-плагин, либо выносить логику в небольшой mu-plugin. Это снижает риск, что при смене темы вы потеряете правку.
Проверка результата после внедрения
После изменения не ограничивайтесь просмотром исходника одной страницы. Нужно проверить несколько сценариев: базовый URL, URL с UTM, URL с сортировкой и URL с тем параметром, который вы решили оставить без изменений.
- Откройте страницу с параметром и посмотрите исходный код.
- Убедитесь, что в
<head>только один canonical. - Проверьте, что canonical указывает на чистый URL без лишних параметров.
- Сравните ответ сервера для URL с параметрами и без них.
- Проверьте, не меняется ли контент при разных параметрах, если canonical одинаковый.
Для быстрой проверки можно использовать:
curl -sL 'https://example.com/page/?utm_source=test' | grep -i 'rel="canonical"'
curl -sL 'https://example.com/page/?sort=asc' | grep -i 'rel="canonical"'Если у вас есть доступ к инструментам для проверки индексации, отправьте на переобход базовый URL и несколько параметризованных вариантов. Это помогает быстрее увидеть, как поисковик интерпретирует новый canonical.
Частые ошибки и как их исправить
Canonical указывает на сам параметризованный URL
Обычно это происходит, когда тема строит canonical из текущего запроса, а не из чистого permalink. Исправление простое: canonical должен собираться из постоянного адреса страницы, а не из $_SERVER['REQUEST_URI'].
На странице два canonical одновременно
Так бывает при конфликте темы и SEO-плагина. Оставьте один источник правды: либо плагин, либо код. Два canonical — это не усиление сигнала, а путаница.
Canonical убирает параметры, которые меняют контент
Это уже ошибка логики. Если фильтр формирует отдельную полезную страницу, не сводите её к базовой версии. В таком случае лучше продумать отдельную посадочную страницу, а не пытаться «починить» её canonical.
Параметры убрали из canonical, но страницы всё равно индексируются
Canonical — это подсказка, а не жёсткий запрет. Если параметризованные URL продолжают массово попадать в индекс, проверьте внутренние ссылки, sitemap, редиректы и наличие noindex там, где это действительно нужно.
Безопасность и производительность: что не стоит делать
Не добавляйте тяжёлую логику в functions.php, если задача касается только canonical. Чем меньше кода в теме, тем проще сопровождать сайт. Для точечных правок лучше использовать маленький mu-plugin: он не зависит от смены темы и не разрастается вместе с шаблонами.
Если вы работаете с большим количеством параметров, не проверяйте каждый запрос через сложные регулярные выражения без необходимости. Достаточно явно перечислить допустимые параметры и работать только с ними. Это проще читать и легче отлаживать.
Если на сайте уже есть чистка дублей и техническая оптимизация через плагин вроде Clearfy Pro, проверьте, не делает ли он часть работы за вас. Иногда проблема не в отсутствии canonical, а в том, что разные инструменты пытаются управлять одним и тем же тегом одновременно. В таких случаях лучше оставить один механизм и убрать дублирующую логику.
В итоге рабочая схема выглядит так: вы определяете, какие параметры должны жить только для пользователя, настраиваете canonical на чистый URL, проверяете исходник и следите, чтобы в head не было конфликтующих тегов. Для WordPress это обычно решается без тяжёлых правок, если не пытаться закрыть одной настройкой сразу все типы URL.