SEO и контент

Canonical на практике: как бороться с дублями страниц и не удалить из поиска нужный URL

На сайте есть две страницы:

https://example.ru/expert/api-timeout

и:

https://example.ru/expert/api-timeout?utm_source=telegram

Контент у них одинаковый.

Для пользователя проблемы почти нет.

Он открыл статью — статья работает.

Для поисковой системы ситуация другая.

Она видит:

URL №1
+
URL №2

и должна решить:

Это два самостоятельных документа или две версии одной страницы?

Если таких вариантов становится много:

?utm_source=
?ref=
?sort=
?page=
http://
https://
www.
без www
со слэшем
без слэша

один реальный материал способен превратиться в десятки технических URL.

Для решения этой задачи существует canonical.

Например:

<link
  rel="canonical"
  href="https://example.ru/expert/api-timeout"
>

Этой строкой страница сообщает поисковой системе:

Основным URL этого содержимого мы считаем именно этот адрес.

Кажется просто.

Но одна ошибка:

<link
  rel="canonical"
  href="https://example.ru/expert"
>

— и уже все статьи раздела могут начать сообщать:

Мы являемся копиями каталога /expert.

В результате разработчик, который хотел убрать дубли, сам создаёт сигнал для исключения нужных страниц из поиска.

Поэтому canonical — это не декоративный SEO-тег.

Это часть архитектуры URL сайта.


Что такое canonical на самом деле

Представим одинаковое содержимое доступно по адресам:

https://example.ru/article
https://example.ru/article/
https://example.ru/article?utm_source=yandex
https://example.ru/article?ref=telegram

Поисковой системе не обязательно хранить четыре копии одного документа.

Google объединяет одинаковые или очень похожие URL в кластер и выбирает один из них в качестве представительного — canonical URL.

Google называет этот процесс canonicalization, или нормализацией URL. При выборе учитываются разные сигналы: redirects, rel="canonical", URL в Sitemap и другие факторы. Причём даже явно указанный владельцем canonical остаётся сигналом: Google может выбрать другой URL, если считает его более подходящим.

Яндекс работает по похожей логике: одинаковые или близкие по содержанию страницы могут быть объединены в группу дублей, после чего для поисковой выдачи выбирается основная страница. rel="canonical" позволяет сообщить Яндексу предпочтительный URL, но и Яндекс рассматривает это как рекомендацию, которую при определённых условиях может не учитывать.

То есть canonical означает не:

«Поисковик обязан показать этот URL».

А:

«Из нескольких одинаковых
или очень похожих вариантов
мы рекомендуем считать
основным этот URL».

Это принципиальная разница.


Зачем вообще бороться с дублями

Представим на сайте опубликовано:

100 статей.

Но из-за параметров, слэшей и технических маршрутов поисковый робот может обнаружить:

2 000 URL.

Контента больше не стало.

Стало больше способов открыть тот же контент.


Дубли расходуют ресурсы обхода

Яндекс прямо указывает, что при наличии дублей робот вынужден обходить несколько страниц вместо одной, что может замедлять обнаружение новых материалов. Кроме того, поисковик способен выбрать в качестве основной не ту страницу, которую владелец сайта хотел видеть в выдаче.

Google также отмечает, что дублирующиеся URL сканируются реже после определения canonical, чтобы уменьшить ненужную нагрузку на сайт.


Дубли усложняют аналитику

Допустим один материал получает переходы на:

/article
/article/
/article?utm_source=direct
/article?ref=partner

Теперь один документ оказывается размазан по нескольким URL.

Отчёты становятся менее понятными.

Внешние ссылки тоже могут вести на разные версии.


Поисковик может выбрать не тот адрес

Например владельцу сайта нужен:

https://example.ru/services/crm

а робот обнаружил ещё:

https://example.ru/services/crm/

и по каким-либо сигналам выбрал вторую версию.

Тогда в выдаче появляется адрес, который сам владелец вообще не собирался продвигать.


Canonical позволяет собрать эти сигналы вокруг одного URL

Но только если он применён правильно.


Первый хороший сценарий: tracking-параметры

Есть статья:

https://example.ru/expert/api-versioning

Для рекламы используется:

https://example.ru/expert/api-versioning
?utm_source=yandex

Для Telegram:

https://example.ru/expert/api-versioning
?utm_source=telegram

Основной контент не меняется.


В таком случае canonical очевиден

На всех вариантах:

<link
  rel="canonical"
  href="https://example.ru/expert/api-versioning"
>

Получается:

/article
          ─┐
/article?utm=... ─┼→ canonical /article
/article?ref=... ─┘

Это классический случай, для которого canonical действительно хорошо подходит.


Но параметры бывают разными

И вот здесь начинается одна из самых частых ошибок.

Разработчик решает:

Всё после ? — дубль.

И создаёт правило:

убрать все query parameters
из canonical.

Это опасно.


Представим интернет-магазин

Есть:

/catalog

и:

/catalog?category=laptops

Если второй URL показывает самостоятельную страницу категории ноутбуков с:

уникальным ассортиментом;
H1;
текстом;
метаданными;

то canonical:

/catalog

может оказаться неправильным.

Мы только что сказали поисковой системе:

Страница ноутбуков не самостоятельна.

Хотя бизнес, возможно, хотел продвигать запрос:

ноутбуки купить

именно через неё.


Поэтому нельзя канонизировать URL только по форме

Нужно смотреть на смысл содержимого.

Например:

?utm_source=

обычно не меняет содержимое.

А:

?category=laptops

может менять его полностью.


Хороший вопрос перед canonical

Не:

Есть ли в URL параметр?

А:

Эти две страницы решают одну и ту же задачу пользователя?

Если да — вероятно, это кандидаты на объединение.

Если нет — canonical между ними может быть ошибкой.


Второй сценарий: слэш и отсутствие слэша

Сервер открывает:

https://example.ru/expert/article

и:

https://example.ru/expert/article/

одинаково.

Теперь поисковый робот видит два адреса.


Лучшее решение часто не canonical, а redirect

Например выбираем:

/expert/article

и на:

/expert/article/

возвращаем:

301 Moved Permanently
Location: /expert/article

Теперь:

/article/
      ↓ 301
/article

Второго реально работающего документа больше нет.

Google относит redirects к сильным canonicalization-сигналам; rel="canonical" тоже является сильным сигналом, а включение URL в Sitemap — более слабым. Эти сигналы можно сочетать.


Когда redirect лучше canonical

Если duplicate URL вообще не нужен пользователю:

старый URL;
www/non-www;
лишний slash;
HTTP-версия;
устаревший маршрут,

лучше часто физически отправить пользователя на основной URL.

Canonical особенно полезен, когда альтернативный URL должен продолжать существовать.

Например tracking URL можно оставить доступным, но поисковой системе показать основную версию.


Простое правило

Если можно сказать:

Этот URL больше никому не нужен.

рассмотрите:

301/308 → основной URL.

Если:

URL нужен технически, но контент тот же.

рассмотрите:

rel="canonical".

Третий сценарий: HTTP и HTTPS

Представим сайт доступен:

http://example.ru/article

и:

https://example.ru/article

Сегодня основной сайт должен работать через HTTPS.

Для старой HTTP-версии логичнее настроить:

HTTP
↓
301/308
↓
HTTPS

а не поддерживать две полноценные версии сайта и надеяться только на canonical.

Яндекс для переноса между HTTP и HTTPS также рекомендует redirects, а не использовать canonical как замену переносу сайта.


То же самое с www и без www

Например выбрано:

https://webruta.ru

Вариант:

https://www.webruta.ru

лучше сразу перенаправлять:

www
↓
301
↓
non-www

или наоборот — главное, чтобы выбор был единым.


Основная ошибка — оставлять обе версии жить независимо

Плохо:

https://example.ru/page → 200

https://www.example.ru/page → 200

и надеяться, что поисковые системы всегда выберут нужную.

Лучше не создавать проблему, которую потом приходится объяснять canonical.


Четвёртый сценарий: CMS создаёт несколько маршрутов к одной статье

Например публикация доступна:

/expert/api-versioning

и одновременно:

/category/backend/api-versioning

и:

/articles/1842

Контент идентичен.


Нужно выбрать архитектурно основной адрес

Например:

/expert/api-versioning

Дальше остальные варианты:

301

или, если они по техническим причинам должны существовать:

canonical
→ /expert/api-versioning.

Нельзя оставлять выбор случайным

Если сегодня Google выбрал:

/articles/1842

а завтра:

/expert/api-versioning,

поисковое представление сайта становится нестабильным.


Пятый сценарий: сортировка

Каталог:

/products

и:

/products?sort=price

Если меняется только порядок тех же товаров:

товары те же;
смысл страницы тот же;

то sort-версия часто является хорошим кандидатом на canonical к основной странице.


Но фильтр — уже не обязательно дубль

Например:

/products?brand=apple

может быть полноценной посадочной страницей:

Apple;
уникальный H1;
отдельный спрос;
отдельный набор товаров.

Тогда canonical на:

/products

способен удалить из поисковой стратегии полезную категорию.


Faceted navigation — одна из самых сложных областей SEO

Комбинации:

brand=apple
color=black
ram=16
sort=price
page=3

могут создать огромное пространство URL.

Google отдельно предупреждает, что faceted navigation способна генерировать практически бесконечное число адресов, из-за чего crawler тратит ресурсы на малоценные URL и медленнее обнаруживает действительно важные страницы.

Но решить это правилом:

«всё с параметрами → canonical /catalog»

нельзя.

Нужно сначала классифицировать фильтры.


Например

utm_source
→ tracking
→ дубль
sort
→ представление
→ обычно дубль
color
→ возможно дубль
brand
→ возможно полноценная landing page
category
→ самостоятельная страница
page
→ отдельная часть пагинации

Такое решение относится уже не к тегу <link>, а к архитектуре каталога.


Шестой сценарий: пагинация

Есть:

/expert
/expert?page=2
/expert?page=3

Очень опасная ошибка:

page 2 canonical → /expert
page 3 canonical → /expert
page 4 canonical → /expert

Почему?

Потому что:

/expert?page=2

содержит другие статьи.

Это не точная копия первой страницы.

Если canonical всех страниц направить на:

/expert,

мы утверждаем:

Все эти страницы — один документ.

Хотя основной список содержимого различается.


Для обычной пагинации self-canonical обычно безопаснее

Например:

/expert
canonical → /expert
/expert?page=2
canonical → /expert?page=2
/expert?page=3
canonical → /expert?page=3

Если проект хочет индексировать пагинацию.

А если ненужные pagination URL вообще не должны участвовать в поиске, эту задачу лучше решать отдельной индексной политикой, а не ложным canonical.


Canonical не является заменой noindex

Это две разные инструкции.

Canonical:

Эта страница похожа на другую; основной считаем другую.

noindex:

Эту страницу вообще не нужно индексировать.

Например внутренний поиск

/search?q=crm

может не иметь никакой SEO-ценности.

Не обязательно говорить:

canonical → /

Технически домашняя страница и search results вообще не являются дублями.

Если поисковая страница не нужна в индексе, честнее применить правильную indexing policy.


Очень плохой анти-паттерн

Все ненужные URL
canonical → главная.

Например:

404
→ canonical /
/search
→ canonical /
/login
→ canonical /
/admin
→ canonical /

Canonical не является SEO-мусорным ведром.


Страницы должны быть действительно одинаковыми или очень похожими

Яндекс прямо указывает: если содержимое canonical и non-canonical страниц существенно различается, робот может проигнорировать canonical и оставить альтернативную страницу в поиске.

Google также советует при проблемах canonicalization проверить, действительно ли объединённые страницы достаточно похожи; если контент существенно различается, их следует делать отдельными документами, а не пытаться насильно объединить.


Самая опасная ошибка: canonical с каждой статьи на каталог

Представим шаблон статьи.

Разработчик хочет добавить:

<link rel="canonical">

и пишет:

canonical =
  `${BASE_URL}/expert`;

вместо:

canonical =
  `${BASE_URL}/expert/${article.slug}`;

Теперь:

/expert/postgresql
/expert/api
/expert/pwa
/expert/seo

все говорят:

canonical → /expert.

Что видит поисковая система

Каталог:

/expert

и десятки страниц:

«Мы не основные.
Основная страница — /expert».

Результатом может стать исключение части материалов как non-canonical.


Визуально сайт при этом полностью исправен

Пользователь открывает статью.

Видит:

H1;
текст;
изображения.

Никакой ошибки.

PageSpeed зелёный.

Backend отвечает 200.

Но поисковый сигнал неверный.


Именно поэтому canonical должен тестироваться автоматически

Для обычной уникальной статьи:

request URL
===
canonical URL

Например:

https://example.ru/expert/api
===
https://example.ru/expert/api

Это self-canonical.


Self-canonical — не ошибка

Иногда разработчик видит:

<link
  rel="canonical"
  href="https://example.ru/expert/api"
>

на самой:

/expert/api

и думает:

Зачем страница ссылается сама на себя?

Так и задумано.

Яндекс прямо подтверждает, что canonical, указывающий на текущую страницу, допустим: робот просто рассматривает эту страницу как каноническую.


Self-canonical особенно полезен при параметрах

Например пользователь пришёл:

/expert/api
?utm_source=telegram

HTML всё равно содержит:

canonical:
/expert/api

Таким образом canonical становится стабильным независимо от tracking URL.


Не вычисляйте canonical напрямую из полного Request URL

Плохой вариант:

canonical = request.url;

Теперь:

/article?utm_source=yandex

получает:

canonical =
/article?utm_source=yandex.

А:

/article?utm_source=telegram

получает другой canonical.

Мы только что узаконили все tracking-дубли.


Canonical должен строиться из нормализованной модели URL

Например:

protocol = https

host = example.ru

path = canonical pathname

allowed SEO parameters =
только явно разрешённые

а не:

скопировать всё,
что прислал браузер.

Ещё опаснее использовать Host header без проверки

Например production находится:

example.ru

Но приложение построило canonical по входящему host.

Через внутренний proxy оно получает:

localhost:4173

И HTML внезапно содержит:

canonical:
http://localhost:4173/expert/article

Поэтому production base URL лучше контролировать явно

Например:

PUBLIC_BASE_URL=
https://example.ru

и валидировать при startup.

Если environment содержит:

localhost

production deployment должен падать ещё до публикации.


Canonical на staging — отдельная проблема

Представим тестовый сайт:

staging.example.ru

копирует production.

Если staging открыт поисковикам и содержит self-canonical:

staging.example.ru/...

поисковик обнаруживает второй сайт с тем же содержимым.


Лучше не надеяться на canonical для защиты staging

Тестовая среда обычно вообще не должна индексироваться.

Используйте:

authentication;
network restriction;
noindex;

и другие средства, соответствующие инфраструктуре.

Canonical не является системой защиты staging.


Что делать со старым URL после переименования slug

Было:

/expert/api-timeout

Стало:

/expert/pochemu-timeout-api-opasen

Если старый адрес больше не нужен:

старый
↓
301
↓
новый.

Это лучше, чем оставить обе страницы 200 и только прописать canonical.


Почему redirect здесь естественнее

Пользователю тоже не нужна старая версия URL.

Значит:

redirect

решает сразу две задачи:

пользователь оказывается на новом URL;

и:

поисковику передаётся сильный сигнал переноса.

Canonical не должен создавать цепочки

Плохо:

A
canonical → B

B
canonical → C

Гораздо понятнее:

A → C
B → C
C → C

Яндекс прямо указывает цепочки canonical среди случаев, когда указание может не учитываться.


Ещё хуже циклы

A canonical → B
B canonical → A

Сайт говорит:

A основная B.

И одновременно:

B основная A.

Поисковику остаётся игнорировать часть противоречивых сигналов и принимать решение самостоятельно.


Canonical URL должен быть доступен

Представим:

/article-a
canonical → /article-b

Но /article-b:

404

или:

noindex

или:

301 → /article-c.

Получилась плохая цепочка сигналов.

Яндекс прямо предупреждает: canonical может быть проигнорирован, если целевая страница недоступна роботу, перенаправляет дальше или сама закрыта от индексирования.


Хороший canonical должен вести сразу на конечную страницу

Ожидаем:

canonical URL
↓
200 OK
↓
indexable
↓
self-canonical

Не:

canonical
↓
301
↓
301
↓
200.

Canonical и Sitemap должны говорить одно и то же

Страница:

/article?ref=partner

говорит:

canonical → /article.

Но sitemap содержит:

/article?ref=partner.

Получаются противоположные сигналы.


Лучше

Sitemap:

<loc>
https://example.ru/article
</loc>

Canonical:

https://example.ru/article

Внутренние ссылки:

https://example.ru/article

Redirect policy:

также приводит к /article.

Именно согласование сигналов делает canonical сильнее

Google прямо указывает, что canonicalization-сигналы могут складываться: redirect и rel="canonical" являются сильными сигналами, а Sitemap — более слабым; их согласованное использование увеличивает вероятность выбора предпочитаемого URL.


Хорошая архитектура выглядит так

Internal links
      │
      ▼
 /canonical-url
      ▲
      │
Sitemap
      ▲
      │
rel=canonical
      ▲
      │
redirects

Все системы показывают на один адрес.


Плохая

Internal link
→ /article/

Sitemap
→ /article

Canonical
→ /articles/1842

Old redirect
→ /blog/article

Четыре сигнала — четыре адреса.

Неудивительно, если поисковик выберет пятый вариант самостоятельно.


Canonical и JavaScript

На SPA может происходить:

Первоначальный HTML:

<link
  rel="canonical"
  href="https://example.ru/expert"
>

После загрузки JavaScript:

canonical.href =
  'https://example.ru/expert/article';

Получается два последовательных сигнала.


Лучше не создавать конфликт

Google рекомендует по возможности задавать canonical непосредственно в HTML. Если canonical устанавливается JavaScript, не следует сначала отдавать один canonical, а затем изменять его на другой.

То есть:

SSR HTML

должен сразу содержать правильную каноническую ссылку.


Для SEO-страницы это ещё один аргумент за серверное формирование <head>

Сервер уже знает:

article.slug;
public URL;
indexability.

Значит он способен сразу отдать:

<link
  rel="canonical"
  href="https://example.ru/expert/article"
>

Не ждать hydration.


Canonical можно задавать и через HTTP header

Это особенно полезно для не-HTML ресурсов.

Например два URL PDF:

/files/offer.pdf

и:

/archive/offer.pdf.

В самом PDF невозможно добавить HTML:

<link rel="canonical">

Но сервер может вернуть:

Link: <https://example.ru/files/offer.pdf>; rel="canonical"

Яндекс официально поддерживает такой вариант для файлов вроде PDF.

Google также поддерживает rel="canonical" через HTTP header для документов, где HTML-тег неприменим.


Но нужен ли вообще второй PDF URL?

Снова возвращаемся к архитектуре.

Если второй адрес не нужен:

redirect

будет проще.

Canonical полезен тогда, когда альтернативный ресурс по какой-то причине действительно должен оставаться доступным.


Canonical и разные языки

Есть:

/ru/article
/en/article

Это не дубли только потому, что смысл текста одинаков.

Русская и английская страницы предназначены для разных языковых аудиторий.

Обычно каждая имеет self-canonical:

/ru/article
→ canonical /ru/article
/en/article
→ canonical /en/article

а связь языковых вариантов описывается через:

hreflang.

Нельзя сделать

/en/article
canonical → /ru/article

только потому, что английская статья является переводом.

Так можно попросить поисковик исключить нужную языковую версию.


Google прямо разделяет canonicalization и localization

Региональные страницы с очень похожим контентом могут нуждаться и в canonicalization, и в hreflang, в зависимости от конкретной структуры, но языковые страницы нельзя бездумно склеивать только из-за совпадающего смысла.


Canonical и A/B-тесты

Представим:

/product

и временный вариант:

/product-test-b.

Контент почти один и тот же.

Google рекомендует при A/B-тестах использовать canonical с тестовых URL на оригинальный адрес, а для временных redirects использовать временный 302, а не постоянный 301.

Это хороший пример canonical по прямому назначению:

несколько временных вариантов
одного документа
→ один основной URL.

Canonical не исправляет плохой контент

Представим две региональные страницы:

/crm-moscow
/crm-kazan

На обеих:

99% одинакового текста.

Разработчик ставит self-canonical:

Москва → Москва
Казань → Казань.

Но self-canonical не является командой:

Считать эти страницы уникальными.

Поисковик всё равно анализирует содержимое

Google может объединить страницы в duplicate cluster и выбрать одну из них, несмотря на предпочтительный canonical владельца.

Яндекс также способен самостоятельно определить страницы как дубли.


Поэтому canonical не создаёт уникальность

Он помогает выбрать основную версию уже похожего содержимого.

Если бизнес хочет две самостоятельные посадочные страницы, они должны иметь реальную самостоятельную ценность.


Canonical и одинаковые TITLE — тоже не одно и то же

Две страницы могут иметь одинаковый:

<title>
CRM для бизнеса
</title>

но содержать разные материалы.

Это проблема metadata.

Но она ещё не делает страницы дублями автоматически.

Яндекс отдельно диагностирует одинаковые TITLE и description и рекомендует делать их содержательными и различимыми.


Не нужно лечить дубли TITLE canonical’ом

Если:

/article-a
/article-b

— две разные статьи, но получили один TITLE из-за ошибки шаблона, нужно исправлять:

TITLE generator.

Не:

article-b canonical → article-a.

Иначе метаданные починили ценой исключения страницы.


Canonical и noindex вместе

Представим:

<meta
  name="robots"
  content="noindex"
>

и:

<link
  rel="canonical"
  href="/article"
>

на одной странице.

Мы одновременно говорим:

Не индексируй меня.

и:

Я являюсь дублем вот этой страницы.

Такие смешанные сигналы лучше не создавать без осознанной причины.


Если страница является дублем

Используйте:

canonical.

Если страница вообще не должна быть в поиске:

noindex

или другую подходящую индексную политику.

Не нужно навешивать всё сразу «для надёжности».


Canonical и robots.txt

Ещё одна ошибка:

Disallow: /filters/

а внутри этих страниц находится:

canonical → /catalog.

Если crawler вообще не получает документ, он может не увидеть canonical внутри него.

Это плохой способ управления дублями.


Индексирование и crawling — разные уровни

Canonical должен быть доступен поисковому роботу как сигнал.

Не стоит сначала блокировать роботам доступ к странице, а потом ожидать, что они прочитают её <head>.


Canonical не нужен абсолютно каждой технической странице

Например:

/admin
/api/internal

вообще не предназначены для поискового индекса.

Там важнее:

authentication;
authorization;
indexing policy.

Canonical не является механизмом безопасности.


Главная практическая ошибка — создавать canonical автоматически без классификации страниц

Например общий helper:

canonical =
  BASE_URL + pathnameWithoutQuery;

кажется универсальным.

Но:

/products?brand=apple

может потерять:

brand=apple

хотя именно он делает страницу самостоятельной.


Поэтому генератор должен знать тип страницы

Например:

expert_article
→ canonical by slug
service_page
→ canonical by route
tracking_variant
→ remove tracking params
search_results
→ not canonicalized to arbitrary page
filter_landing
→ explicit SEO policy
pagination
→ pagination policy

Canonical становится результатом бизнес-правила.

Не механической строковой операции.


Можно создать явный SEO-контракт

Например:

{
  type: 'expert_article',
  indexable: true,
  canonicalStrategy: 'self',
  sitemap: true
}

Для tracking:

{
  type: 'tracking_variant',
  indexable: false,
  canonicalStrategy: 'base-url'
}

Для категории:

{
  type: 'category',
  indexable: true,
  canonicalStrategy: 'self',
  sitemap: true
}

Теперь правило видно в коде.


Как тестировать canonical

Для обычной статьи:

GET /expert/article

ожидаем:

canonical =
https://example.ru/expert/article

Для tracking URL

GET /expert/article?utm_source=test

ожидаем:

canonical =
https://example.ru/expert/article

Для другой статьи

GET /expert/article-b

canonical не должен неожиданно стать:

/expert/article-a.

Особенно полезно проверить уникальность canonical

Есть:

200 статей.

Собираем:

200 canonical URLs.

Для обычных уникальных материалов ожидаем:

200 уникальных canonical.

Если получилось:

17,

явно сломан общий generator.


Это невероятно сильный regression test

Один ошибочный template способен исключить:

сотни страниц.

Один тест:

canonical uniqueness

может остановить такой release.


Проверяем hostname

Ожидаем:

webruta.ru

а не:

localhost;
staging;
старый домен;
www при политике без www.

Проверяем HTTPS

canonical protocol =
https.

Проверяем fragment

Обычный canonical страницы не должен случайно выглядеть:

/article#comments.

Проверяем tracking parameters

Не должно быть:

utm_source;
utm_campaign;
yclid;
gclid;
ref,

если они не изменяют содержимое и по правилам проекта не входят в канонический URL.


Проверяем canonical target по HTTP

Для каждого canonical:

GET canonical

ожидаем:

200.

Не:

404;
500;
301 chain.

Проверяем self-canonical target

Если:

A canonical → B,

то страница B обычно должна отвечать:

canonical → B.

Не:

B → C.

Проверяем Sitemap

Для индексируемой статьи:

canonical URL

должен совпадать с URL в:

sitemap.xml.

Google прямо рекомендует указывать в Sitemap именно те URL, которые владелец хочет видеть в поисковой выдаче, то есть основные canonical-версии.


Проверяем внутренние ссылки

Карточка статьи должна ссылаться:

на canonical URL.

Не на tracking-вариант.

Не на старый slug.

Не на URL, который потом перенаправляется.


В итоге поисковику не приходится угадывать

Sitemap       ─┐
Internal links ├→ /article
Canonical      ┤
Redirects     ─┘

Как диагностировать ситуацию «Google выбрал другой canonical»

В Search Console можно увидеть:

User-declared canonical

и:

Google-selected canonical.

Если они отличаются, не нужно сразу считать:

Google ошибся.

Google рекомендует сначала проверить технические сигналы и затем убедиться, что страницы, которые система объединила в один кластер, действительно достаточно отличаются друг от друга.


Вы указали:

/product-red

как self-canonical.

Но:

/product-red

и:

/product-blue

имеют практически идентичное содержание.

Google выбрал:

/product.

В таком случае проблема может быть не в canonical-теге.

Проблема:

страницы фактически недостаточно различаются.

То же стоит проверять в Яндекс Вебмастере

Яндекс позволяет увидеть excluded pages и статус:

Duplicate

или:

non-canonical.

Это намного информативнее, чем просто проверять:

site:example.ru.

А что если нужная страница уже выпала из поиска из-за неправильного canonical?

Допустим статья:

/expert/article

ошибочно несколько недель имела:

canonical → /expert.

Исправляем:

<link
  rel="canonical"
  href="https://example.ru/expert/article"
>

После этого проверяем весь набор сигналов

HTTP 200 ✓

noindex отсутствует ✓

robots разрешает ✓

canonical self ✓

sitemap содержит article ✓

internal links ведут на article ✓

После переобхода поисковая система сможет переоценить URL.


Но результат не обязан измениться мгновенно

Google предупреждает, что после исправления canonicalization потребуется время на повторный обход и перерасчёт duplicate cluster; в некоторых случаях страницы могут оставаться объединёнными до нескольких недель.

Яндекс также обновляет состояние после следующего обхода и обработки изменений.


Не нужно пытаться «усилить» исправление десятком противоречивых инструментов

Например:

canonical self
+
noindex
+
robots Disallow
+
удаление из Sitemap

если вы хотите вернуть страницу в индекс.

Так мы одновременно говорим:

Это моя основная страница.

и:

Не индексируйте её.

Для возвращения страницы нужна последовательность

indexable;
accessible;
200;
self-canonical;
sitemap;
internal links.

Дальше нужно дать crawler возможность обновить данные.


Canonical не должен использоваться для удаления страницы

Представим устаревшая статья:

/old-api-guide

больше вообще не нужна.

Новая статья:

/new-api-guide

полностью её заменяет.

Если соответствие действительно прямое, логичнее:

301 → /new-api-guide.

Если замены нет

Например старая акция:

/promo-2024

закончилась.

Canonical на главную:

/

не делает главную эквивалентом старой акции.

Нужно выбрать корректный HTTP/indexing lifecycle страницы.


То есть canonical отвечает только на один вопрос

Какой URL является главным среди эквивалентных или очень похожих документов?

Он не отвечает:

Страница удалена?
Страница приватная?
Страница устарела?
Страница плохая?
Нужно сделать redirect?

Для этих задач существуют другие механизмы.


Как выбирать между redirect, canonical и noindex

Удобная практическая схема.

Два URL содержат одно и то же, альтернативный больше не нужен

Используем:

301/308.

Пример:

/old-slug
→
/new-slug.

Два URL нужны пользователям, но контент практически одинаков

Используем:

rel="canonical".

Например:

/article?utm_source=...
→ canonical /article.

Страница нужна пользователю, но вообще не нужна в поиске

Рассматриваем:

noindex

или соответствующую индексную политику.

Например определённые внутренние результаты поиска.


Страница самостоятельна и должна участвовать в поиске

Используем:

self-canonical.

И не склеиваем её с другой страницей только ради «SEO-чистоты».


Когда canonical вообще не нужен для решения проблемы

Например две статьи имеют похожие TITLE.

Решение:

развести TITLE.

Две страницы отличаются только регистром URL:

/CRM
/crm

Лучше нормализовать URL и настроить redirect.


HTTP и HTTPS доступны параллельно:

redirect → HTTPS.

Старый slug:

redirect → новый slug.

То есть canonical — один инструмент среди нескольких.

Не универсальный ответ на любой duplicate warning.


Практический пример для Экспертного центра

Представим опубликована статья:

/expert/canonical-na-praktike

Основной HTML:

<head>
  <title>
    Canonical на практике:
    как бороться с дублями страниц
  </title>

  <link
    rel="canonical"
    href="https://example.ru/expert/canonical-na-praktike"
  >
</head>

Пользователь приходит из Яндекс Директа:

/expert/canonical-na-praktike
?utm_source=yandex
&utm_campaign=seo

Сервер отдаёт тот же материал.

Canonical остаётся:

/expert/canonical-na-praktike.

Telegram:

?utm_source=telegram

Canonical тот же.


Sitemap:

<loc>
https://example.ru/expert/canonical-na-praktike
</loc>

Карточка в /expert:

<a
  href="/expert/canonical-na-praktike"
>

Получается единая картина:

Tracking URLs
     │
     ▼
Canonical
     │
     ▼
/expert/canonical-na-praktike
     ▲
     │
Sitemap
     ▲
     │
Internal links

Вот для чего canonical действительно нужен.


Теперь другой пример

Созданы:

/expert?page=1
/expert?page=2
/expert?page=3

На второй странице находятся другие статьи.

Если написать:

все canonical → /expert,

мы больше не боремся с техническими дублями.

Мы начали объявлять самостоятельное содержимое дублем.

Вот здесь canonical уже работает против сайта.


Ещё один пример: услуги

Есть:

/services/crm

и:

/services/saas

Шаблон одинаков.

Но содержимое и intent различаются.

Нельзя сделать:

/services/saas
canonical → /services/crm

только потому, что обе страницы созданы одним React-компонентом.


Технический шаблон не определяет SEO-дублирование

Поисковику интересен основной контент.

Не то, какой компонент его отрисовал.


Ещё один опасный случай — fallback canonical

Разработчик пишет:

const canonical =
  page.canonical || '/';

Если CMS по какой-то причине не заполнила canonical, статья получает:

canonical → homepage.

Это один из худших fallback.


Безопаснее fail closed

Если indexable SEO-страница не может вычислить правильный canonical:

publication error

или:

build fails.

Не:

«поставим главную, чтобы тег был».

Отсутствующий canonical зачастую безопаснее заведомо неправильного.

Google способен выбрать canonical самостоятельно, если сайт его вообще не указал.


То есть SEO-генератор должен уметь отказать

Например:

SEO validation failed:

page:
/expert/article

reason:
canonical URL cannot be resolved

Статья не публикуется до исправления.

Это значительно лучше скрытой массовой ошибки.


Что проверять перед production

Для всех индексируемых страниц:

  • canonical существует;
  • canonical абсолютный;
  • используется HTTPS;
  • host соответствует production;
  • tracking parameters удалены;
  • canonical относится к правильной сущности;
  • целевой URL возвращает 200;
  • canonical target не имеет noindex;
  • target не redirect;
  • нет canonical chain;
  • self-canonical указан на основной версии;
  • Sitemap содержит именно canonical URL;
  • внутренние ссылки ведут на canonical URL;
  • разные самостоятельные страницы не получили одинаковый canonical;
  • staging/localhost никогда не появляются в canonical;
  • пагинация не склеена с первой страницей без осознанной причины;
  • языковые версии не склеены между собой просто из-за одинакового смысла;
  • filter URLs классифицированы по смыслу, а не только по наличию query parameters.

Очень сильный автоматический тест — карта canonical

После build можно создать таблицу:

URLCanonicalHTTP
/expert/a/expert/a200
/expert/b/expert/b200
/expert/c/expert/c200

Если внезапно получается:

URLCanonical
/expert/a/expert
/expert/b/expert
/expert/c/expert

CI сразу останавливает release.


Ещё один тест — обратный индекс canonical

Например система видит:

canonical /expert
← 147 самостоятельных article URLs

Это подозрительно.

Для некоторых страниц такая группировка нормальна.

Но для 147 разных статей — почти наверняка ошибка.


Canonical можно тестировать как граф

Правильная модель:

A → A

B → B

C?utm=x → C

C?utm=y → C

Неправильная:

A → B
B → C
C → A

или:

A → B
B → C

Это особенно удобно для большого сайта

Когда URL уже тысячи, ручная проверка <head> больше не работает.

Canonical становится именно тем SEO-правилом, которое очень хорошо проверяется программно.


Как действовать, если дубли уже появились в индексе

Сначала классифицировать причину.

Например:

tracking params
slash
HTTP/HTTPS
www/non-www
CMS routes
filter combinations.

Потом выбрать один основной URL.


Следующий шаг — привести все сигналы к нему

redirects;
canonical;
sitemap;
internal links.

Не только добавить один <link> и закончить работу.


Затем проверить реальный HTTP

Потому что application code может говорить:

canonical correct.

А Nginx:

redirects elsewhere.

Затем посмотреть Search Console и Яндекс Вебмастер

Google URL Inspection показывает, какой canonical объявил сайт и какой выбрал Google.

Yandex Webmaster показывает страницы, исключённые как duplicate/non-canonical.


Не стоит ждать мгновенной перестройки индекса

Роботу нужно:

снова обнаружить URL;
обойти;
прочитать новые сигналы;
пересобрать duplicate cluster.

Это асинхронный процесс.


Canonical на практике — это прежде всего дисциплина URL

Лучший сайт — не тот, у которого на каждой странице есть сложный <link rel="canonical">.

А тот, у которого:

один документ
→ один понятный основной URL.

Не:

/article
/article/
/article?id=1842
/blog/article
/article?ref=menu

как пять равноправных путей.

А:

/article

— основной.

Остальные либо:

redirect,

либо:

технические варианты
с canonical → /article.

Чем чище routing, тем меньше работы canonical

Canonical не должен исправлять хаотичную архитектуру сайта постфактум.

Он должен дополнять уже нормализованную URL-модель.


Практическая таблица решений

СитуацияОбычно разумный подход
UTM-параметрыCanonical на чистый URL
Старый slug301/308 на новый
HTTP → HTTPSRedirect
www → без wwwRedirect
Trailing slash duplicateRedirect/единая routing policy
Сортировка одинакового набораЧасто canonical к базовой странице
SEO-фильтр с уникальным intentSelf-canonical
Технический фильтрCanonical/noindex/crawl policy по архитектуре
Пагинация с разным содержимымНе склеивать автоматически с page 1
Внутренний поискНе canonical на главную; отдельная indexing policy
Две языковые версииОбычно self-canonical + hreflang
Устаревшая страница с прямой заменойRedirect
PDF-дублиHTTP canonical либо redirect
A/B-вариантCanonical на оригинал

Самый опасный вопрос звучит так

На какую страницу нам поставить canonical?

Начинать нужно раньше:

Это вообще дубль?

Если ответ:

нет,

canonical на другую страницу уже подозрителен.


И только если страницы действительно эквивалентны

спрашиваем:

Какой URL должен стать главным?

Именно в таком порядке

Compare content / intent
        ↓
Duplicate?
   /           \
 no             yes
 │               │
self            choose
canonical       primary URL
                 │
         ┌───────┴─────────┐
         ▼                 ▼
 duplicate needed?     duplicate obsolete?
         │                 │
         ▼                 ▼
     canonical          redirect

Это намного безопаснее правила:

«нашли два URL —
ставим canonical».

Вместо вывода

Canonical нужен для очень конкретной задачи:

помочь поисковой системе выбрать основной URL среди нескольких одинаковых или очень похожих страниц.

Например:

/article
/article?utm_source=yandex
/article?utm_source=telegram

вполне логично объединить вокруг:

/article.

Но:

/article-a
/article-b

нельзя склеивать только потому, что они используют один шаблон.

Так же как:

/catalog
/catalog?brand=apple

необязательно являются дублями только потому, что второй URL содержит query parameter.

Главная опасность canonical заключается в его внешней простоте.

Одна строка:

<link rel="canonical" href="...">

может повлиять на то, какой URL останется кандидатом для поисковой выдачи, а какой будет рассматриваться как его вариант или дубль.

Поэтому правильная последовательность выглядит так:

Определить смысл страницы
        ↓
Найти реальные дубли
        ↓
Выбрать основной URL
        ↓
Настроить redirects,
где duplicate больше не нужен
        ↓
Настроить canonical,
где duplicate должен существовать
        ↓
Привести Sitemap
к тому же URL
        ↓
Исправить внутренние ссылки
        ↓
Проверить production HTTP
        ↓
Запустить regression tests

Именно так canonical перестаёт быть SEO-заклинанием.

Он становится обычным инженерным контрактом:

для этого содержимого основным является вот этот URL.

А главный принцип остаётся очень простым:

если две страницы действительно нужны поиску как два самостоятельных документа, не нужно объединять их canonical только ради борьбы с дублями.

Потому что удалить технический дубль полезно.

А случайно сообщить поисковой системе, что нужная вам страница является дублем другой, — уже полноценная SEO-регрессия.

Есть похожая задача?

Опишите продукт, интеграции и ограничения. До разработки зафиксируем объём, риски и критерии приёмки.

Обсудить проект →