Настройка canonical в WordPress для страниц с параметрами

Если в 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.

⭐⭐⭐⭐⭐