У сайта, который одновременно обслуживает Россию, Казахстан и Беларусь, рано или поздно появляются отдельные версии: свои цены, своя валюта, свои условия доставки и свои юридические подробности. И вот тут начинается путаница. Москвич видит в поиске казахстанскую страницу с тенге, покупатель из Алматы попадает на белорусский каталог, а владелец сайта ломает голову над странной статистикой конверсии. Атрибут hreflang создан для таких ситуаций: разметка объясняет поисковой системе, какая страница предназначена для какой аудитории. Google читает эти подсказки и показывает человеку подходящую версию. Яндекс устроен иначе: там работают собственные региональные сигналы, и без понимания обеих механик настройка превращается в работу вслепую.
Назначение hreflang и логика языковых привязок в поиске
Технически hreflang - это значение атрибута rel внутри тега link. Запись с rel="alternate" и hreflang="ru-KZ" сообщает роботу: у страницы есть версия для русскоязычной аудитории Казахстана, её адрес записан в атрибуте href. Набор таких записей объединяет несколько страниц в группу взаимозаменяемых версий: основную для России, региональные для Казахстана и Беларуси, при необходимости белорусскоязычную.
Зачем поиску эта группа? Без подсказки система вынуждена выбирать одну страницу из похожих и показывать её всем подряд. Региональные версии не получают собственного трафика, а посетитель видит чужую валюту и чужой склад, после чего уходит без заказа. С аннотациями картина меняется: Google понимает, что страницы равноправны и обслуживают разные аудитории, поэтому в выдаче для пользователя из Казахстана открывает именно казахстанский адрес.
Разметка остаётся подсказкой, а не командой. Поисковик вправе проигнорировать аннотацию, если заявленный язык не соответствует содержимому. Ссылочный вес между версиями hreflang не переносит: каждую версию продвигают отдельно, слабую казахстанскую страницу не спасёт даже идеальная строка в коде. И ещё одно условие: версии должны реально существовать. Если один сайт обслуживает все три страны без разделения, hreflang не нужен вовсе.
Три способа задания hreflang и выбор варианта под структуру сайта
Закрепить группу аннотаций на сайте можно одним из трёх путей, и выбор зависит от размера проекта и от того, кто управляет шаблонами:
- link-теги с rel="alternate" в блоке head каждой страницы;
- секция с тегами xhtml:link внутри XML-карты сайта;
- HTTP-заголовки Link в ответе сервера.
Первый способ нагляднее остальных. Разработчик добавляет в шаблон вывод link-тегов, и дальше разметка обновляется автоматически. Для страницы каталога это выглядит примерно так:
<link rel="alternate" hreflang="ru-RU" href="/site.ru/catalog/">
<link rel="alternate" hreflang="ru-KZ" href="/site.kz/catalog/">
<link rel="alternate" hreflang="ru-BY" href="/site.by/catalog/">
<link rel="alternate" hreflang="be-BY" href="/site.by/be/catalog/">
<link rel="alternate" hreflang="x-default" href="/site.ru/catalog/">
В живом проекте адрес в атрибуте href записывают полностью, с протоколом и доменом; здесь адреса сокращены ради читаемости. Слабое место подхода: блок ссылок держится на аккуратности шаблонов. Сломался вывод в одном разделе - и целая группа версий потеряла взаимность.
Второй способ держит разметку в одном месте, внутри XML-карты. В корневом элементе файла объявляют пространство имён xhtml, затем для каждой страницы в её секцию url добавляют группу тегов, по строке на каждую версию:
<url>
<loc>site.ru/catalog/</loc>
<xhtml:link rel="alternate" hreflang="ru-RU" href="/site.ru/catalog/"/>
<xhtml:link rel="alternate" hreflang="ru-KZ" href="/site.kz/catalog/"/>
<xhtml:link rel="alternate" hreflang="ru-BY" href="/site.by/catalog/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="/site.ru/catalog/"/>
</url>
Ту же группу повторяют в записях всех остальных версий. Карта удобна, когда страниц тысячи: правки не трогают шаблоны, файл генерирует система управления. Обратная сторона: после изменения адресов карту нужно пересобирать, иначе разметка и сайт живут разными жизнями.
Третий способ применяют для адресов без HTML-разметки, например для PDF-прайсов. Ссылку передают заголовком ответа сервера:
Link: <site.kz/files/price.pdf>; rel="alternate"; hreflang="ru-KZ"
Смешивать способы допустимо: одна и та же ссылка в head страницы и в карте ошибкой не считается. Конфликт начинается там, где один код ведёт на разные адреса.
Коды языков и регионов для версий из России, Казахстана и Беларуси
Значение hreflang собирают из двух частей, разделённых дефисом: сначала код языка по стандарту ISO 639-1, затем код страны по ISO 3166-1 Alpha 2. Для русскоязычного проекта с региональными версиями базовый набор выглядит так: ru-RU для России, ru-KZ для Казахстана и ru-BY для Беларуси. Белорусскоязычной версии достаётся код be-BY, а казахскоязычной подходит kk-KZ. Читается значение как "версия на русском языке для пользователей из Казахстана".
Пара "язык плюс страна" нужна тогда, когда контент различается по регионам, а не по языку. Типовой случай: единый каталог на русском языке, внутри которого для каждой страны меняются цены, валюта, сроки доставки и реквизиты. Аннотации различаются только страной: ru-RU, ru-KZ, ru-BY. Когда появляется белорусскоязычная версия, в группу добавляют be-BY: одна страница для Беларуси обслуживает русскоязычную аудиторию, другая собирает тех, кто ищет на белорусском.
Коды из одного языка тоже существуют, например просто ru. Но региональную задачу они не решают: такая пометка объединяет все русскоязычные страницы независимо от страны и не помогает жителю Минска увидеть именно белорусскую версию.
Постоянный источник ошибок кроется в опечатках: трёхбуквенные регионы вроде ru-RUS, перепутанные местами язык и страна, лишние пробелы. Некорректный код поисковик молча отбрасывает, и страница выпадает из группы. Язык принято записывать строчными буквами, страну заглавными. Наконец, разметка не отменяет адаптацию: аннотация be-BY честно работает там, где текст действительно написан на белорусском, а казахстанская страница с рублями и московскими адресами выдаёт слабое соответствие заявленному региону.
Взаимность аннотаций и страница по умолчанию для аудитории из других стран
Главное правило разметки: аннотации обязаны быть взаимными. Каждая страница группы ссылается на все прочие версии и на саму себя. Если российская страница ссылается на казахстанскую, а ответной ссылки нет, Google отбрасывает пару целиком. Самоссылка тоже обязательна: в блоке каждой страницы присутствует строка с её собственным кодом и адресом.
Это правило ломается незаметно: поправили шаблон на одной версии, пережили редизайн, из блока выпала одна строка - и вся группа рассыпалась. Поэтому взаимность проверяют сверкой: набор ссылок на каждой версии обязан совпадать буквально, строка в строку.
Значение x-default закрепляет версию для пользователей, чей язык или регион не покрыт остальными кодами. Для русскоязычных проектов с тремя странами типовое решение: отправить такого посетителя на основную российскую версию либо на страницу выбора страны. Если на сайте есть англоязычная версия, именно её обычно назначают запасной.
Все ссылки в группе должны вести на канонические страницы: финальные адреса без редиректов, параметров отслеживания и следов старой структуры. Если казахстанская версия закрыта канонической ссылкой на российский домен, поисковик получает два противоположных указания: hreflang называет страницы равноправными, а канонический тег объявляет одну из них дублем. Чаще побеждает каноническая ссылка, региональная страница выпадает из индекса, а с ней теряет смысл вся группа. Каждый адрес в группе обязан отдавать код 200: ссылка на страницу с ошибкой 404 или на редирект ломает пару.
Региональные сигналы Яндекса и настройка версий сайта через Вебмастер
Яндекс разметку hreflang напрямую не использует. Для него языковые и региональные связи страниц складываются из собственных наблюдений: региональных настроек в сервисе Вебмастер, содержания страниц, доменной зоны и поведения аудитории.
Со страниц Яндекс считывает конкретные вещи: адреса офисов и пунктов выдачи, телефонные коды, упоминания городов в текстах, валюту цен, условия доставки, реквизиты компании. Доменные зоны .ru, .kz и .by работают как самостоятельные региональные подсказки. Выдача меняется и от региона поиска: человек, указавший в настройках свой город, чаще видит сайты своей страны.
Практический вывод для владельцев трёх версий: каждая версия должна быть самостоятельной с точки зрения Яндекса. Свой домен или поддомен, свои адресные данные, своя региональная информация в контенте, отдельная карта сайта. Если все три страны живут в подпапках одного домена с общим текстом, поисковику трудно отличить их друг от друга, и региональная выдача становится непредсказуемой.
Хорошая новость: hreflang в коде Яндексу не мешает, поисковик его просто не читает. Для Google разметка продолжает работать. Общий каркас для обеих систем выглядит так: корректные аннотации для Google, полноценные региональные сигналы и настройки в Вебмастере для Яндекса.
Типичные ошибки, из-за которых разметка hreflang перестаёт работать
Самая массовая проблема связана с невзаимностью. Страница для Казахстана ссылается на российскую, а ответной ссылки нет или она ведёт на устаревший адрес. Поисковая система отбрасывает повреждённую пару, и пользователь снова видит случайную версию.
Дальше идут ошибки в самих кодах. Трёхбуквенные регионы, выдуманные значения, перепутанный порядок записи, лишние пробелы: некорректные записи молча выбрасываются из группы. Опасность в масштабе: одна опечатка в шаблоне тиражируется на тысячи страниц и остаётся незамеченной месяцами.
Отдельный конфликт создают канонические ссылки, направленные с региональных версий на основной домен. Поисковик получает два противоположных указания и чаще верит каноническому. Региональные страницы выпадают из индекса, и разметка теряет смысл, хотя формально строки на месте.
Свою долю хаоса вносят переезды. Сайт сменил структуру адресов, а в шаблонах и карте остались старые ссылки. Аннотации ведут на перенаправления или на несуществующие страницы, а поисковая система ждёт финальные адреса без переходов. Замыкает перечень самая незаметная история: новую версию забыли добавить во все блоки, белорусскоязычная страница живёт сама по себе, а часть аудитории уходит не туда.
Проверка аннотаций и поддержание разметки в актуальном состоянии после запуска сайта
Для небольшого сайта из трёх или четырёх версий проверка умещается в ручной осмотр: открыть исходный код каждой версии и сверить блок ссылок строка за строкой. Полезно смотреть не только главную, но и типовые страницы каталога и карточек: шаблоны различаются.
На крупных проектах разметку сверяют программно. Краулер проходит по страницам, собирает все аннотации и строит отчёт: у каких страниц не совпадают группы, какие адреса отдают редиректы, где встречаются неизвестные коды. Ошибки видны и в Search Console, а со стороны Яндекса смотрят индексирование каждой версии в Вебмастере.
Порядок поддерживают простыми привычками. После каждого релиза, затрагивающего шаблоны, следует сверка блоков. После изменения адресов следует пересборка карты. При запуске новой страны строку с её кодом добавляют сразу во все блоки и в карту, а не по мере вспоминания.
Возвращаться к разметке стоит при каждом изменении структуры: новые версии, переезды, смена доменов, объединение каталогов. В остальном это спокойная механическая работа: один раз настроить верные пары, проверить взаимность и не оставлять поиску противоречивых указаний. Именно такая аккуратность отделяет сайты, у которых региональные версии доходят до своих аудиторий, от сайтов, где три похожие страницы месяцами спорят между собой за место в выдаче.