Перейти к содержимому

Дубли и канонизация: как свести один смысл к одному URL

  • Правило одно: один смысл — один URL. Всё остальное в этой статье — способы его соблюсти, когда сайт сопротивляется.
  • За дубли не штрафуют. Это первое, что нужно принять: никакого «фильтра за дублированный контент» у Google нет, он просто выбирает из группы одинаковых страниц одну и показывает её. Проблема не в наказании, а в том, что выбирает он не всегда ту, что нужна вам.
  • rel="canonical" — подсказка, а не команда. Google называет это strong signal, но прямо пишет: «indicating a canonical preference is a hint, not a rule».
  • Сигналы складываются. Редирект, canonical, sitemap и внутренние ссылки работают вместе, и если они противоречат друг другу, вы просто отдали выбор роботу.
  • robots.txt для канонизации не годится: закрытую в нём страницу Google может проиндексировать без содержимого, а ваш canonical и noindex он на ней не прочитает — он её не скачает.
  • Пагинацию не сворачивают на первую страницу. Google прямо просит: у каждой страницы пагинации свой собственный canonical на саму себя.
  • Для фильтров и сортировок Google сегодня рекомендует в первую очередь robots.txt, а canonical и nofollow честно называет «менее эффективными в долгую». Это расходится с привычкой многих оптимизаторов.
  • Инструмент управления URL-параметрами из Search Console убрали ещё в 2022 году. Параметры теперь целиком ваша забота.
  • Самый быстрый способ узнать правду — «Проверка URL» в Search Console. Она показывает и заявленный вами канонический адрес, и выбранный Google. Расхождение между ними и есть ваша задача.

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

Формулировка проблемы простая. Для человека site.ru/tovar/kran/ и site.ru/tovar/kran/?sort=price — одна и та же страница, он даже не заметит разницы. Для поисковика это два разных документа, и он должен решить, какой из них показывать. Ваша работа — не заставлять его решать.

Разберу по механизмам, потому что «дубли это плохо» — бесполезная фраза, из неё не следует, что чинить в первую очередь.

Сигналы размазываются. Внешние ссылки, поведенческие, возраст — всё это накапливается на конкретном URL. Если на один товар ведут ссылки с четырёх разных вариантов адреса, то ни один из них не собирает полную картину. Google умеет консолидировать сигналы внутри группы дублей, но делает это по своей модели и не всегда полностью.

В выдаче оказывается не та страница. Самый обидный сценарий. Вы вылизали карточку, а в поиске висит её версия с UTM-меткой из рассылки — без нормального тайтла в истории, зато с хвостом параметров в адресе. Или вместо категории показывается её отфильтрованная версия с двумя товарами.

Обход уходит в никуда. На крупных сайтах это главный эффект. Робот тратит время на пятнадцать тысяч комбинаций фильтров вместо новых карточек. Google в своей документации по фасетной навигации пишет об этом прямым текстом: краулеры сначала обойдут огромное число бесполезных URL и только потом поймут, что они бесполезны, а времени на новые полезные страницы останется меньше. Подробнее — в статье про краулинговый бюджет.

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

/tovar/kran/ /tovar/kran http://site.ru/tovar/kran/ /tovar/kran/?utm_source=vk /tovar/kran/?sort=price /catalog/?filter=kran Одна каноническая страница /tovar/kran/

Источников примерно шесть, и они очень по-разному чинятся.

Самый базовый слой, который должен быть закрыт на любом сайте. Один и тот же контент открывается по http и https, с www и без, со слэшем на конце и без него, а иногда ещё и по /index.php. Для Google это разные URL. Заглавные и строчные буквы в пути, кстати, тоже дают разные адреса.

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

UTM-метки, идентификаторы сессий, партнёрские метки, ?from=, ?ref=. Технически это тот же документ, но с хвостом. Опасны они не сами по себе, а когда просачиваются в индексируемое пространство: кто-то поставил ссылку с UTM-меткой на сторонний сайт, робот её нашёл, и вот у вас в индексе версия с меткой.

Здесь работает rel="canonical" на чистый адрес. Важное дополнение, про которое забывают: не ставьте UTM-метки на внутренние ссылки собственного сайта. Отслеживать внутренние переходы через UTM — распространённая ошибка аналитиков, которая ломает и статистику, и индексацию.

Здесь начинается взрослая задача. Фасетная навигация в интернет-магазине порождает комбинаторный взрыв: цвет × размер × бренд × цена × наличие × сортировка — и вот уже сотни тысяч адресов, за каждым из которых почти тот же список товаров.

Стандартный совет из статей — «поставьте canonical на категорию». Google сегодня говорит иначе, и это стоит знать. В руководстве по фасетной навигации первой рекомендацией идёт запрет обхода таких URL в robots.txt, вторым вариантом — вынос фильтров во фрагмент после решётки (его Google просто не сканирует), а rel="canonical" и nofollow там прямо названы «в долгую менее эффективными».

Логика понятна, если помнить про обход: canonical робот прочитает только после того, как скачает страницу, то есть бюджет уже потрачен. robots.txt останавливает его раньше.

Мой практический подход такой. Сначала решите, какие фильтры вам нужны в поиске: обычно это одиночные значимые фильтры вроде бренда или крупной характеристики, под которые есть спрос. Их делаете полноценными посадочными страницами со своим тайтлом, текстом и самоканоникалом. Всё остальное — комбинации из двух и более фильтров, сортировки, виды отображения, постраничные хвосты фильтров — закрываете от обхода. И следите, чтобы фильтры собирались в предсказуемом порядке: если ?brand=x&color=y и ?color=y&brand=x дают разные URL, вы удвоили проблему на ровном месте.

Отдельный пункт, потому что миф живучий. Страницы 2, 3, 4 в списке товаров — не дубли первой страницы, у них другое содержимое. Правильная схема простая: у каждой страницы пагинации канонический адрес указывает на неё саму. Google просит об этом прямо: «Don’t use the first page of a paginated sequence as the canonical page».

Что не работает: сворачивать все страницы на первую канониклом (потеряете из индекса товары, которые есть только на пятой странице), закрывать пагинацию в noindex целиком (робот перестанет ходить по ссылкам с этих страниц, и глубокие карточки останутся необойдёнными), полагаться на rel="next" и rel="prev" — Google не использует их с 2019 года.

Отдельная беда — страницы «показать всё» и бесконечная прокрутка на скриптах. Если товары подгружаются по скроллу и у них нет обычных ссылок на страницы, робот их не увидит. Про это подробнее в JavaScript SEO.

Технически разные страницы, а по смыслу одно и то же. Варианты товара по цвету и размеру с отдельными URL и одинаковым описанием. Печатные версии. Карточки, где описание — копипаст из каталога поставщика, как и у ста других магазинов. Пустые или почти пустые категории и теги, которые CMS создаёт автоматически.

Эти лечатся не техникой, а решением: либо объединять в одну страницу с выбором варианта, либо действительно различать содержимым. Если у вас двадцать карточек одного крана в разных цветах и текст в них идентичен — вы не обманете поисковик добавлением слова «синий» в тайтл.

Ваш контент на чужих доменах: синдикация в агрегаторы, републикация партнёрами, парсеры. Если публикация согласована, партнёра стоит попросить поставить rel="canonical" на ваш оригинал или хотя бы noindex. Работает не всегда, но просить надо.

Сюда же — региональные и языковые версии. Важный нюанс: версии для разных стран не канонизируются друг на друга. У каждой свой canonical на саму себя, а связывает их hreflang. Скрестить одно с другим — типовая ошибка, после которой из индекса пропадает то, что вы старались развести по аудиториям.

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

На выбор влияют несколько сигналов, и полезно понимать их вес:

СигналСилаКомментарий
Редиректсильныйцель редиректа становится канонической
rel="canonical"сильныйно всё-таки подсказка, а не команда
https против httpзаметныйпри прочих равных Google предпочтёт защищённую версию
Наличие URL в sitemapслабыйпомогает, но сам по себе ничего не решает
Внутренние ссылкикосвенныйто, куда вы ссылаетесь сами, читается как ваше предпочтение

Ключевое здесь — сигналы складываются. Один canonical, которому противоречат все внутренние ссылки и sitemap, работает хуже, чем согласованный набор. Именно поэтому я всегда проверяю не только тег, но и то, на какие адреса ведут ссылки в меню, хлебных крошках и карточках листинга.

ИнструментКогда применятьЧто реально делает
301адрес больше не нужен: зеркала, старые URL после переездаубирает старый адрес из индекса, передаёт сигналы на новый
rel="canonical"обе страницы должны работать для людей, но в индексе нужна однаподсказывает предпочтительный адрес, консолидирует сигналы
noindexстраница нужна пользователям, но в поиске не нужна: корзина, личный кабинет, служебныеубирает из индекса, при этом робот продолжает ходить по ссылкам
robots.txtмассивы мусорных URL, которые незачем даже скачивать: комбинации фильтров, сортировкизапрещает обход, экономит бюджет, но не гарантирует отсутствие в индексе
hreflangязыковые и страновые версии одного смыслане консолидирует, а разводит версии по аудиториям

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

  1. Закрываю зеркала. Одна версия хоста, один вариант со слэшем, 301 одним переходом. Проверяю руками все четыре комбинации.
  2. Ставлю самоканоникалы. На каждой индексируемой странице canonical на саму себя, абсолютным адресом, в <head>. Это дешёвая страховка от случайных параметров.
  3. Разбираюсь с параметрами. UTM и сессии — canonical на чистый адрес, внутренние ссылки без меток.
  4. Решаю по фильтрам. Список нужных в поиске фильтров, всё остальное закрываю от обхода.
  5. Чиню пагинацию. Самоканоникал на каждой странице, никаких сворачиваний на первую.
  6. Свожу сигналы. Внутренние ссылки, меню, хлебные крошки и sitemap ведут ровно на канонические адреса, а не на редиректы и не на версии с параметрами.
  7. Проверяю результат в Search Console — и это уже не разовая задача, а наблюдение на пару месяцев.

Список из того, что я вижу в аудитах регулярно.

  • Канонический адрес указывает на страницу, которая редиректит или отдаёт 404. Сигнал противоречив, Google выберет сам.
  • Цепочки канониклов: A ссылается на B, B на C. Указывайте сразу конечный адрес.
  • Canonical стоит в <body>. Google принимает его только из <head>. Часто это следствие сломанной вёрстки: незакрытый тег выбрасывает остаток разметки из шапки.
  • Относительные адреса вместо абсолютных. Формально поддерживаются, но ошибиться в базовом пути легко, и тогда canonical уедет в несуществующий URL.
  • Несколько тегов canonical на одной странице — обычно потому, что один поставила CMS, а второй SEO-плагин. Google в такой ситуации игнорирует оба.
  • Canonical, проставляемый скриптом. Работает, но только после рендеринга, а до него робот видит страницу без него.
  • Sitemap с неканоническими адресами — вы сами себе противоречите.
  • Canonical между языковыми версиями вместо hreflang.
  • Закрыли в robots.txt то, что уже в индексе, и ждёте выпадения. Не выпадет: чтобы увидеть noindex, роботу нужен доступ.

Три источника, и они дополняют друг друга.

Search Console, «Проверка URL». Самое точное, что есть. Вводите адрес и смотрите два поля: «Канонический URL, объявленный пользователем» и «Канонический URL, выбранный Google». Если они различаются — Google с вами не согласился, и дальше нужно понять почему.

Search Console, отчёт «Индексирование страниц». Здесь живут целые категории проблем: «Страница является копией: отправленный URL не выбран в качестве канонического», «Страница является копией: Google выбрал не ту страницу, что и пользователь», «Страница является копией без канонической версии, выбранной пользователем». Последняя категория особенно полезна — это места, где вы вообще не высказали предпочтения.

Краулер. Screaming Frog или Netpeak Spider обходят сайт как робот и показывают одинаковые тайтлы и описания, страницы с почти совпадающим содержимым, канониклы, ведущие не туда, и адреса с параметрами, на которые вы сами ссылаетесь. Регулярный обход и сравнение с предыдущим — лучший способ поймать момент, когда новый релиз создал десять тысяч дублей.

Оператор site: для этого годится плохо. Он даёт грубую оценку и легко вводит в заблуждение точным числом, которого на самом деле нет. Как ориентир «стало сильно больше страниц, чем я ожидал» — сойдёт, как измерение — нет.

  • Все зеркала (http/https, www/без, слэш/без) сведены 301-редиректом к одной версии за один переход.
  • На каждой индексируемой странице есть rel="canonical" на саму себя, абсолютным адресом, в <head>.
  • Тег canonical на странице ровно один.
  • Канонические адреса отдают 200 и не ведут на редиректы.
  • UTM-меток нет на внутренних ссылках сайта.
  • Определён список фильтров, нужных в поиске; остальные комбинации закрыты от обхода.
  • Параметры фильтров собираются в стабильном порядке.
  • У страниц пагинации самоканоникал, а не canonical на первую страницу.
  • Языковые версии связаны hreflang и канонизированы каждая на себя.
  • Одна и та же страница не закрыта одновременно в robots.txt и через noindex.
  • Sitemap содержит только канонические адреса, отдающие 200.
  • Внутренние ссылки, меню и хлебные крошки ведут на канонические адреса.
  • В Search Console нет роста категории «Страница является копией».