Содержание

Про hreflang ходят два убеждения: «90% сайтов делают его неправильно» и «мельчайшая ошибка выключает его целиком, лучше не использовать». Я проверил оба по документации Google, высказываниям сотрудников поиска и чужим исследованиям, а потом измерил сам: главные страницы 5 000 доменов из списка Tranco. Главная получена у 2 946, hreflang нашёлся у 912, выборка смещена к крупным и служебным доменам. Число 90% я не нашёл ни в одном из просмотренных источников. Нарушение правил Google нашлось у 19% сайтов с hreflang в моей выборке, а неверный код Google отбрасывает по одной ссылке. Вместе с ней пропадает возврат для пары, а шаблонная ошибка повторяется на всех страницах, так что на практике выпадает язык целиком. Страницу целиком отключают другие поломки (раздел 7). Как проверить свой сайт: чек-лист и валидатор в разделе 9.

Что вы узнаете
  • Верны ли два убеждения. Что говорят Google и измерения Ahrefs, Semrush, Search Engine Land, и что показал мой замер на 912 сайтах.
  • Какие коды путают и важен ли регистр. Страна вместо языка, uk вместо en-GB, es-419, подчёркивание, fil.
  • Как выглядит правильный hreflang. Рабочий код для HTML, HTTP-заголовка и sitemap, с разбором, какой способ выбрать.
  • Какие ошибки не про коды. Закрытый head, canonical на другой язык, редиректы, noindex, перенаправление по IP.
  • Что делать. Порядок проверки, таблица из 208 строк «неправильно → правильно» и валидатор, которые можно скачать.
31,0%главных страниц с hreflang: 912 из 2 946 полученных у доменов из топ-5000 Tranco
19,2%сайтов с hreflang нарушают хотя бы одно правило справки Google: 175 из 912
8,0%сайтов с неверным кодом языка или страны хотя бы в одной аннотации: 73 из 912
10,1%сайтов, где хотя бы у одной проверенной альтернативы нет ссылки назад: 82 из 814
Что такое hreflang

Hreflang — разметка, которая сообщает поисковику, что у страницы есть версии на других языках или для других стран. Google использует её, чтобы показать пользователю нужную версию вместо той, которая нашлась в индексе. По словам Google, на ранжирование разметка не влияет. Джон Мюллер (Google), 28 марта 2018 года: «It doesn't change rankings, but helps to get the "right" URL swapped in for the user» («Она не меняет ранжирование, но помогает подставить пользователю нужный URL»).

Что hreflang делает и чего не делает

Разметка работает как справочник соответствий: «эта страница — английская для США, вот её немецкий двойник, вот запасная». Из документации и высказываний Google следует четыре ограничения, которые часто забывают.

Hreflang подменяет URL в выдаче

Мюллер (Reddit, 24 июня 2022 года): страницы разных доменных зон с одинаковым содержимым Google может склеить в один canonical, а hreflang всё равно подставляет нужный адрес. Search Console при этом отчитывается по canonical: «Search Console generally reports on the canonical URLs».

Язык страницы определяется не по ней

Справка Google: «Google doesn't use hreflang or the HTML lang attribute to detect the language of a page; instead, we use algorithms to determine the language.» Google язык по тегу lang и мета content-language не определяет; для других поисковиков их лучше оставить.

Сила между версиями не делится

Гэри Иллис (Google, Reddit, 8 февраля 2019 года): «Within the cluster the signals aren't passed around». Версия на другом языке не наследует сигналы соседней.

Нужен не всегда

Мюллер, 28 марта 2018 года: «Use it if you see the wrong country/language version ranking, otherwise you probably don't need it». У сайта на одном языке разметка «doesn't do anything anyway».

Google называет три случая, где разметка оправдана: переведён только шаблон (меню и подвал), есть мелкие региональные различия внутри одного языка (английский для США, Великобритании и Ирландии) или контент полностью переведён. Переведённые версии дублями не считаются: Google относит страницы к дублям, «only if the main content of the page remains untranslated». Одна оговорка: справка Google допускает, что языковые версии он находит и без разметки, но «it is usually best for you to explicitly indicate» их.

Три тезиса и что по ним нашлось

01

«90% сайтов делают hreflang неправильно»

источника нет

Число 90% не встретилось ни в одной работе. Измерения дают от 31% (частный показатель: конфликтующие директивы) до 75% в зависимости от метода. Мой замер: 19,2% сайтов с нарушением правил Google на главной (175 из 912); среди 814 сайтов с проверенной альтернативой 22,4% с учётом ссылок назад и 23,6% (192 из 814) с добавлением выводов из высказываний Google.

02

«Мельчайшая ошибка выключает hreflang»

частично

Неверная ссылка игнорируется сама, остальные работают. Но нет ссылки назад — игнорируется пара, а закрытый раньше времени head сбрасывает разметку страницы целиком.

03

«Лучше не использовать hreflang»

узко

Верно для сайтов без дублей между рынками и для связей между не-переводами. Неверно, если Google показывает не ту версию: тогда разметка нужна. Измерений вреда от самих ошибок я не нашёл ни у одной из сторон.

Тезис 1. «90%»: что измеряли другие

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

Рисунок 1

Чужие измерения: доля сайтов с ошибкой

у каждой работы свой метод
Semrush, 2017
20 000 сайтов с несколькими языками
75%
Ahrefs, 2023
374 756 доменов с hreflang
67%
seotal, 2026
2 300 сайтов с юго-восточной локалью
53,1%
Dan Taylor (Search Engine Land), 2023
18 786 сайтов, только конфликтующие директивы
31%
Мой замер
912 сайтов, нарушение правил Google на главной
19,2%
Шкала 0–100%. Столбцы нельзя сравнивать между собой: у каждой работы свой набор проверок, единица счёта и выборка.
Выборки и методы чужих измерений (таблица 1)
Таблица: чужие измерения доли ошибок в hreflang
Кто и когдаВыборкаДоля
Semrush, 2017 (по пересказу Search Engine Journal)20 000 сайтов с несколькими языками из клиентов Site Audit; цель исследования названа открыто: привлечь внимание SEO-специалистов к проблемам hreflang75%
Ahrefs, 2023374 756 доменов, которые используют hreflang; хотя бы одна проблема67%
seotal, 20262 300 сайтов с юго-восточной локалью среди 11 106 сайтов с hreflang (из 50 497 прочитанных главных страниц); данные от 13 сентября 2026 года, часть проверок авторские53,1%
Dan Taylor (Search Engine Land), 202318 786 сайтов из NerdyData, только hreflang в head; 31% — доля сайтов с конфликтующими директивами, а не с любой ошибкой31%

Внутри этих работ видно, из чего складываются проценты. Ahrefs отдельно называет отсутствие x-default у 56,3% доменов, отсутствие самоссылки у 18%, ссылки на редирект или битую страницу у 16,9%, отсутствие ссылок назад у 15,3%, hreflang на неканоническом URL у 8% и неверные значения у 4,6%. Semrush оценивает конфликты в коде страницы в 58% сайтов, причём в 96% случаев не хватало самоссылки. Две популярные цифры, «72% (Ahrefs, 2026)» и «одна ошибка обнуляет примерно 40% реализаций», я проследить до источника не смог, поэтому в статью они не вошли.

Тезис 2. «Мельчайшая ошибка выключает hreflang»

Google описывает точечное поведение. Мюллер, Reddit, 26 апреля 2018 года: «If hreflang isn't valid (non-indexed pages linked, invalid language codes) then it's ignored & the same as not having it at all (this is on a per-hreflang-link basis, so if some are ok, they'll work)» («Если hreflang невалиден, он игнорируется, как будто его нет; это происходит для каждой ссылки отдельно, так что рабочие продолжают работать»). Иллис, office hours, январь 2023 года: кластер строится из ссылок, которые Google смог подтвердить, а страница с noindex в кластер не попадает: «The cluster will be created regardless with the other valid links».

Есть исключения, когда ломается больше одной ссылки.

Схема 1

Кластер с одним потерянным возвратом

иллюстрация, адреса условные
✕ нет возврата взаимная ссылка взаимная ссылка enexample.com/en/ de-DEexample.com/de-de/ ruexample.com/ru/
  • Пара взаимная: страницы ссылаются друг на друга, пара работает.
  • Страница en заявляет de-DE альтернативой, но ответа нет.
  • У de-DE нет ссылки на en: пара en и de-DE игнорируется, пары с ru остаются.
Правило справки Google: «If two pages don't both point to each other, the tags will be ignored». Ссылки страниц на себя на схеме не показаны.

Итог: Google отбрасывает неверную ссылку, но остальные пары кластера работают, если у них есть возврат. Если же ошибка стоит в шаблоне, она повторяется на каждой странице и выключает этот язык по всему сайту. Разметку страницы целиком отключают структурные поломки; их видно только в отрисованном HTML. Источники расходятся в одном месте: в 2022 году Иллис (по пересказу Search Engine Roundtable, оригинал я не открывал) говорил, что noindex у одного URL «can affect the whole cluster», добавив «hard to trigger it, but nonetheless, you can»; в 2023 году он сказал, что кластер создаётся и без такой страницы. Я принимаю более позднее и более подробное заявление, но на сайте с noindex в кластере его стоит проверять на живых данных.

Тезис 3. «Лучше не использовать»

За тезис есть три довода. Связь между не-переводами хуже, чем отсутствие разметки (раздел 2). Бонуса к ранжированию нет. А в конкурентной выдаче, по словам Мюллера (13 августа 2021 года), разметка «just makes it a lot harder for you to kind of grab more foothold there»: версии для разных стран приходится наращивать каждую отдельно. Есть и описания просадок после внедрения, например с 3 тысяч кликов в день до нескольких сотен (самоотчёт на Webmasters StackExchange), но причина в hreflang нигде не доказана.

Против тезиса говорят два довода, причём второй сводится к осторожному выводу. Мюллер (18 июня 2021 года): «i think there's definitely no disadvantage to using it». А в кейсе Clarks (Sistrix, 2020) до миграции hreflang не было вовсе, после переезда на новый домен его добавили с четырьмя проблемами: теги не на canonical-адресах, нет self-canonical, нет ссылок назад, не задан x-default. Против hreflang этот случай не говорит, как и в защиту: это неисправная разметка среди прочих правок.

61%

ключей Clarks в Испании показывали адрес чужого рынка после миграцииВидимость в Испании упала с 1,579 до 0,050. Sistrix называет причиной сумму изменений: «Too many changes all at the same time».

Схема 2

Нужен ли hreflang вашему сайту

мой вывод по источникам
  1. 1
    На сайте есть версии для разных языков или стран?

    Нет Hreflang не нужен: у сайта на одном языке разметка «doesn't do anything anyway».

    Да Перейдите к вопросу 2.

  2. 2
    В выдаче показывается не та версия: чужая страна или язык?

    Да Нужен. Мюллер советует включать разметку именно в этом случае.

    Нет Перейдите к вопросу 3.

  3. 3
    Несколько стран на одном языке или переведено больше пары разделов?

    Да Нужен.

    Нет Не нужен, пока версии разных стран не конкурируют друг с другом и Google показывает правильные адреса.

  4. →
    Если решили внедрять

    Начинайте с малого кластера, который можно проверить целиком. Языки без реальной версии пропустите: Google такое разрешает. Каждой версии нужен отдельный URL. Дальше идите по порядку проверки из раздела 9.

Мюллер: «Use it if you see the wrong country/language version ranking, otherwise you probably don't need it». Дерево собрано из этой цитаты и пунктов справки Google, а не из измерений.

Замер главных страниц доменов из топ-5000 Tranco

Выборка: первые 5 000 доменов списка Tranco (список создан 18 октября 2026 года), замер 19 октября 2026 года. Главная страница получена и разобрана у 2 946 сайтов. У 912 из них (31,0%, 95% интервал 29,3–32,7%) есть hreflang в HTML или в заголовке ответа. Дальше доли считаются от этих 912 сайтов, если не сказано иное. Проверка шла по правилам справки Google: это замер соответствия документации, а не доказательство, что Google отбросил разметку.

Рисунок 2

От выборки до нарушений

главные страницы · 5 000 доменов Tranco

Главная получена у 2 946 сайтов, hreflang есть у 912

Среди 912 сайтов с hreflang: нарушает хотя бы одно правило Google — 175

есть hreflangнарушено правило справки Googleнарушений нет
Доли второй строки считаются от 912 сайтов с hreflang.
Рисунок 3

Нарушения правил Google на главных страницах

доля от 912 сайтов с hreflang
Неверный код языка или страны хотя бы в одной аннотации
8,0%73 сайта
Нет самоссылки
6,6%60 сайтов
Canonical главной ведёт на другую страницу кластера (среди 840 с canonical)
5,8%49 сайтов
Не абсолютный URL хотя бы в одной аннотации
1,3%12 сайтов
У <link hreflang> нет rel="alternate"
0,4%4 сайта
<link hreflang> в body, а не в head
0,2%2 сайта
Хотя бы одно из перечисленных
19,2%175 сайтов
Шкала 0–20%. Точные числа и 95% интервалы — в таблице 2 ниже.
Таблица 2: числа сайтов и 95% интервалы
Таблица: нарушения правил Google на главных страницах
НарушениеСайтовДоля95% интервал
Неверный код языка или страны хотя бы в одной аннотации738,0%6,4–9,9%
Нет самоссылки606,6%5,1–8,4%
Canonical главной ведёт на другую страницу кластера (среди 840 с canonical)495,8%4,4–7,6%
Не абсолютный URL хотя бы в одной аннотации121,3%0,8–2,3%
У <link hreflang> нет rel="alternate"40,4%0,2–1,1%
<link hreflang> в body, а не в head20,2%0,1–0,8%
Хотя бы одно из перечисленных17519,2%16,8–21,9%

Запрос альтернатив добавляет проверку обратных ссылок. Я проверил до шести альтернатив на каждом сайте и получил ответ хотя бы от одной у 814 сайтов. У 82 из них (10,1%, интервал 8,2–12,3%) хотя бы у одной альтернативы нет ссылки назад в HTML или заголовке. Из sitemap возврат я не проверял, это завышает долю; лимит в шесть альтернатив, гео-редиректы и ответы защиты от ботов смещают оценку в обе стороны, поэтому число приблизительное. С учётом возврата хотя бы одно нарушение правил Google есть у 182 из 814 сайтов (22,4%). Если добавить выводы из высказываний Google (один код на разные URL, несколько x-default, canonical главной не равен её адресу), получается 192 из 814 (23,6%, интервал 20,8–26,6%). Без нарушений обоих уровней остаётся 622 сайта (76,4%).

Рисунок 4

Три уровня проверки

доля сайтов с нарушением
Только главная
175 из 912 сайтов
19,2%
С обратными ссылками
182 из 814 сайтов
22,4%
И выводы из высказываний Google
192 из 814 сайтов
23,6%
Шкала 0–30%. Первый столбец считан от 912 сайтов, два других — от 814 с проверенной альтернативой.

К строке про неверный код: из 73 сайтов 39 используют только fil, es-419 и ckb. Эти значения допустимы по BCP 47, но вне списков ISO из справки Google. Как Google их обрабатывает, я не проверял. Если убрать 32 сайта, у которых это единственное нарушение, останется 143 из 912 (15,7%); пересчёт сделан после просмотра данных, интервал не считался.

Рисунок 5

Как меняется доля при другой классификации

в каждом пересчёте меняется одно допущение
Основной расчёт
175 из 912 сайтов
19,2%
Без сайтов, у которых единственное нарушение — fil, ckb, es-419 или числовой регион
143 из 912 сайтов
15,7%
Без повторов конечных адресов главных
170 из 849 сайтов
20,0%
Шкала 0–25%. Оба пересчёта сделаны после просмотра данных, интервалы для них не считались. Основа расчёта у столбцов разная: 912 и 849 сайтов.

Что ещё нашлось, но ошибкой не считается

28,7%Нет x-default: у 262 сайтов (28,7%). Это рекомендация Google, не требование.
33,6%Код записан строчными (en-gb): у 306 сайтов (33,6%), целиком заглавными не записан ни один код в выборке. Google принимает оба регистра.
99,3%Где стоит hreflang: в head он есть у 906 из 912 сайтов (99,3%), в том числе у 12, где он продублирован в заголовке. Только в заголовке ответа — у 4, только в body — у 2.
10,5%Редирект на альтернативе: хотя бы одна альтернатива отвечает редиректом у 87 из 826 сайтов (10,5%). В итог 19,2% эта строка не вошла, но считать такую пару исправной не стоит: аннотации на неканоническом адресе, по словам Мюллера, «would not be used», а возвратная ссылка с конечной страницы указывает на другой URL.
Какие значения кодов оказались неверными

Неверный код в хотя бы одной аннотации есть у 73 сайтов. Всего проверено 16 861 аннотация, неверных 389 (2,3%). Больше всего аннотаций дают трёхбуквенные языки (277 аннотаций на 34 сайтах), подчёркивание вместо дефиса (30 на 4), числовой регион (20 на 19 сайтах, почти всегда es-419), неизвестный регион (20 на 11), регион вместо языка (7 на 5). Самые частые значения: es-419 (19 сайтов), fil (16), fil-ph (7), ckb (5), pt_br (3), en-eu (3). Значения fil, ckb, es-419 допустимы по BCP 47, но не входят в ISO 639-1 и ISO 3166-1, на которые ссылается справка Google. Из 73 сайтов 39 используют только такие значения (этот срез я выделил после просмотра данных, он не был заложен в метод). Как Google реально обрабатывает fil, я не проверял и опираюсь на букву справки.

sitemap: что нашлось в выборке из 300 сайтов

У 300 случайных сайтов с hreflang я просмотрел sitemap из robots.txt (до шести файлов на сайт). Директива Sitemap: есть у 196 из них (65,3%), хотя бы один файл прочитан у 187. Атрибуты xhtml:link с hreflang нашлись в просмотренной части у 50 сайтов (25,5% от 196). Главная страница найдена в sitemap у 101 сайта, у 26 из них в записи главной есть hreflang. У 17 из этих 26 набор «код — URL» совпал с HTML-разметкой, у 9 отличался. Это нижняя оценка: большие sitemap просмотрены частично. Расхождение наборов между способами — прямой путь к конфликту, о нём в разделе 7.

Как считалось и что нельзя из этого выводить
  • Единица счёта — сайт (домен). Главная — страница https://домен/ после редиректов. Доли даны с 95% интервалом Уилсона, рассчитанным в предположении независимости сайтов; 204 из 2 946 главных повторяют конечный адрес более высокого домена, поэтому интервалы немного оптимистичны. Без этих повторов доля сайтов с нарушением 170 из 849 (20,0%) вместо 175 из 912 (19,2%).
  • Читался сырой HTML без выполнения JavaScript, с учётом robots.txt (главная закрыта для нашего бота у 177 доменов). Hreflang, который появляется только после скриптов, в замер не попал.
  • Из 5 000 доменов главная не получена у 2 054: 1 187 недоступны (в основном SSL-ошибка на инфраструктурных доменах без публичного сайта), 515 ответили отказом или проверкой, остальные — прочие ошибки. Выборка смещена к крупным и служебным доменам, поэтому результат нельзя переносить на небольшие сайты: там доля может быть выше и ниже.
  • Измерена только главная. Внутренние страницы, каталоги и карточки, где разметку чаще генерируют плагины и шаблоны, не проверялись.
  • Запросы шли из одной точки сети (выход в Швеции), с языком браузера en-US. Сайты, которые выбирают версию по IP, могли показать одну из своих версий.
  • Замер не оценивает влияние на позиции и трафик и не показывает, как Google обработал конкретную разметку.

Правила Google: что обязательно, что рекомендовано

Страница справки «Tell Google about localized versions of your page» обновлена 21 сентября 2026 года. Из неё на практике следуют десять правил.

  1. Каждая версия перечисляет себя и все остальные«Each language version must list itself as well as all other language versions». Нет самоссылки — нарушение правила (6,6% сайтов в моём замере).
  2. Ссылки взаимныеЕсли страница А указывает на Б, а Б не указывает на А, теги игнорируются; Google объясняет это защитой от чужих деклараций.
  3. URL полные, с протоколомhttps://example.com/foo, а не //example.com/foo и не /foo. Схема обязательна: адрес без неё не годится. Требование Google.
  4. Набор ссылок одинаков на каждой версииДля HTML и для заголовка Link. В sitemap каждая запись содержит весь набор, включая себя.
  5. Коды: язык ISO 639-1, регион ISO 3166-1 Alpha 2Регион отдельно, без языка, указывать нельзя. Скрипт по ISO 15924 допустим (zh-Hant), регистр не важен.
  6. Теги стоят в корректном headСправка советует вставить отрисованный код в валидатор HTML и убедиться, что ссылки внутри head. Рекомендация Google.
  7. Hreflang не смешивают с другими атрибутами в одном linkНапример, с media: на каждый вариант отдельный тег. Требование Google.
  8. x-default — запасная страницаРекомендация, не обязанность. Лучше всего работает на странице выбора языка; языка для него указывать не нужно.
  9. Для нескольких стран на одном языке нужна общая версия языкаРядом с en-IE, en-CA, en-AU Google советует дать страницу en для всех остальных англоязычных мест. Рекомендация Google.
  10. Canonical ведёт на страницу того же языка«make sure to specify a canonical page in the same language». Canonical с атрибутом hreflang Google не использует, а адреса из hreflang-кластеров он предпочитает при выборе canonical. Рекомендация Google.

Способов внедрения три, и для Google они равнозначны: «The three methods are equivalent from Google's perspective». Использовать все сразу можно, но выгоды нет, а управлять тремя реализациями сложнее. Сторонние инструменты проверки, как сказано в справке, «are not maintained or checked by Google», а официального отладчика, по словам Иллиса в подкасте Search Off the Record (2024), у Google нет. Поэтому зелёный отчёт любого сервиса не доказывает, что Google принял разметку.

Коды языка и страны: что путают и что нет

Первая часть кода — язык, вторая, необязательная, — страна. Отсюда две частые путаницы: страну пишут вместо языка, а язык принимают за страну. Таблица собрана по справке Google, реестру языковых тегов IANA (файл от 17 сентября 2026 года) и RFC 5646. Колонки частоты в ней нет сознательно: частоту по отдельным кодам, кроме замера выше, никто не измерял.

Таблица: частые неверные коды hreflang
ПишутЧто это на самом делеПравильно
jp, cnРегионы Япония и Китай; кода языка с такими буквами нетja, zh-CN или zh-Hans
kr, seЯзыки канури и северносаамский, а не корейский и шведскийko, sv
dk, gr, cz, uaТолько регионыda, el, cs, uk
en-UKРегиона UK в реестре нет, Великобритания — GB; Google называет UK среди кодов, которые «doesn't have an effect» (игнорируется весь код или только регион, Google не уточняет)en-GB
uk для Великобританииuk — украинский языкen-GB (для украинского uk верен)
be для БельгииБелорусский язык; пример прямо в справке Googlenl-BE, fr-BE
es-419, en-EU, UNНе поддерживаются Google; es-419 — регион ООН, EU и UN зарезервированыДля es-419: es или отдельные страны (es-MX, es-AR). Для en-EU: en или код страны. Для UN: код языка с регионом или x-default
es-LA, laLA — Лаос, la — латинский язык; это ошибка, только если имелась в виду Латинская Америкаes или отдельные страны
us, GB без языкаРегион без языка; Google язык из страны не выводитen-US, en-GB
GB-enОбратный порядок частейen-GB
en_US, pt_brРазделитель в формате — дефис; в грамматике RFC 5646 подчёркивания нет. Поведение Google не найденоen-US, pt-BR
eng, rus, deuТрёхбуквенные коды; в реестре IANA для таких языков определён только двухбуквенныйen, ru, de
filВалиден по BCP 47, но не входит в ISO 639-1; по букве справки Google не поддерживается, поведение не провереноtl по букве справки; работающую разметку переделывать не обязательно, проверьте выдачу с gl=ph
iw, in, jiУстаревшие коды иврита, индонезийского, идиша; в справке Google о них не сказаноhe, id, yi
zh-CHS, zh-CHTТаких подтегов нет в реестреzh-Hans, zh-Hant
pt-PT и pt-BR наоборотОба кода валидны, ошибка в сопоставлении кода и адреса; синтаксис её не показываетПортугалия — pt-PT, Бразилия — pt-BR

Регистр: пишите en-GB, но Google ошибки не увидит

В справке Google: «The hreflang value is case-insensitive; Google accepts lowercase and uppercase codes, but formatting region codes in uppercase (for example, en-GB) follows ISO 3166-1 Alpha 2 convention». Миф «регистр критичен» опровергают три источника: справка Google, RFC 5646 (регистр смысла не несёт, рекомендуется язык строчными, скрипт с заглавной, регион заглавными) и пример самого Яндекса, где регион записан строчными (en-us, tr-tr). В моём замере 23,2% аннотаций с валидным кодом записаны строчными, целиком заглавными — ни одной. Строчные коды не ошибка: переделывать работающую разметку ради регистра не нужно, а в новой пишите en-GB.

Оговорка о правильном коде

Правильный код ещё не означает правильную разметку. pt-PT и pt-BR, поставленные на противоположные страницы, пройдут любой валидатор. Смысл пары проверяет только человек, и именно такие связи Мюллер называл хуже, чем отсутствие hreflang.

Три способа внедрения и эталонный код

Примеры написаны на условном домене example.com (он зарезервирован для примеров, реального сайта за ним нет). Кластер из четырёх версий: en, en-GB, de-DE, ru, страница выбора языка в корне как x-default. Код сверен с документацией Google и проверен приложенным валидатором: замечаний нет.

Способ 1HTML-теги в head

Обычные страницы, когда нет доступа к sitemap и заголовкам.

Способ 2HTTP-заголовок Link

PDF и другие файлы, где нет head.

Способ 3Sitemap

Большие сайты и каталоги: разметка отделена от шаблонов страниц.

Способ 1. HTML: теги в head

Подходит, когда нет возможности править sitemap и заголовки ответа. Эти же пять строк стоят на каждой из пяти страниц кластера, включая саму страницу выбора языка. Переведённая версия выглядит так (страница https://example.com/en-gb/):

HTML: эталон
<!doctype html>
<html lang="en-GB">
<head>
  <meta charset="utf-8">
  <title>Example Widgets (UK)</title>
  <link rel="canonical" href="https://example.com/en-gb/">
  <link rel="alternate" hreflang="en" href="https://example.com/en/">
  <link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
  <link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
  <link rel="alternate" hreflang="ru" href="https://example.com/ru/">
  <link rel="alternate" hreflang="x-default" href="https://example.com/">
</head>
<body>...</body>
</html>

Способ 2. HTTP-заголовок Link: для PDF и файлов без HTML

Заголовок нужен там, где нет head: PDF и другие файлы. Набор значений одинаков для всех версий и включает запрошенную. Формат следует RFC 8288: адрес в угловых скобках, затем параметры. Все значения hreflang я записал в одной строке через запятую, как в примере Google; несколько отдельных строк Link стандарт допускает, но как с ними поступает Google для hreflang, я не подтвердил.

HTTP-заголовки: эталон для PDF
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Language: de
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru", <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="x-default"
Link: <https://example.com/files/manual-de.pdf>; rel="canonical"

Это ответ на запрос https://example.com/files/manual-de.pdf. На английском и русском файлах заголовок тот же, меняется только строка с canonical.

Способ 3. Sitemap: xhtml:link в каждой записи

Практичнее всего при большом числе языков и URL, потому что страницы не тяжелеют. Нужно объявить пространство имён xmlns:xhtml, а в каждый url положить весь набор альтернатив, включая сам адрес. Один кластер в примере лежит в одном файле. Справка Google о разносе по файлам молчит, а Мюллер (Reddit, 7 июня 2022 года) пишет: «It's fine to split it across sitemap files», главное — взаимная связь, а не место разметки.

sitemap.xml: эталон
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example.com/en/products/widget/</loc>
    <lastmod>2026-10-01</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/products/widget/"/>
    <xhtml:link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/products/widget/"/>
    <xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/produkte/widget/"/>
    <xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/produkty/widget/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/products/widget/"/>
  </url>
  <!-- такая же запись для /en-gb/, /de-de/ и /ru/ с тем же набором из пяти xhtml:link -->
</urlset>
sitemap_index.xml: эталон
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/sitemap.xml</loc>
    <lastmod>2026-10-01</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-zh.xml</loc>
    <lastmod>2026-10-01</lastmod>
  </sitemap>
</sitemapindex>

Как выбрать способ

HTML

  • Для обычных страниц, когда нет доступа к sitemap и заголовкам.
  • Страницы тяжелее, а при сотне языков разметка занимает заметную долю head.
  • Яндекс в справке Вебмастера описывает именно разметку в head.

Sitemap и заголовок

  • Sitemap — для больших сайтов и каталогов: разметка отделена от шаблонов страниц.
  • Заголовок Link — для PDF и других файлов без head.
  • Яндекс, по справке Вебмастера, sitemap для языковых версий больше не поддерживает.

Смешивать способы можно, пока они согласованы. Мюллер (стрим 27 ноября 2020 года): приоритета «sitemap лучше HTML» нет, а конфликт возникает, когда одна пара «язык — страна» указана для разных страниц. Тогда Google, по его словам, «would probably just drop that pair». Отсюда правило: одна пара «язык — страна» указывает на один адрес во всех способах. В моём замере у 9 из 26 сайтов, где главная размечена и в HTML, и в sitemap, наборы различаются.

9 из 26

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

Ошибки не про коды: где реально ломается

Коды проверяет любой валидатор. Следующие ошибки инструменты находят хуже.

Закрытый раньше времени head

Скрипт или noscript с iframe в начале head закрывает его неявно, и теги hreflang оказываются в body. Разбор такого случая в выпуске Google Search Central «SEO Fairy Tales» (2022): iframe внутри noscript закрывает head, «because an iframe shall not be in the head». Проверять нужно отрисованный HTML. Инструменты без рендеринга такое не видят.

Canonical на другой язык

Если canonical французской страницы ведёт на английскую, локализованная страница может свестись к чужой: Google просит указывать canonical на странице того же языка. В моём замере у 5,8% сайтов canonical главной указывает на другую страницу кластера.

Hreflang на неканоническом адресе

Мюллер (office hours, 9 июля 2019 года): если адрес не считается каноническим, Google его не покажет, и «any annotation that's associated with that URL would not be used». Адреса с параметрами и UTM в hreflang не нужны.

Альтернатива отвечает редиректом, 404 или закрыта

Страница с noindex в кластер не попадает (Иллис), а Ahrefs относит ссылки на редирект и битую страницу к ошибкам. В моём замере у 87 сайтов хотя бы одна альтернатива отвечала редиректом, у 13 — ошибкой 4xx или 5xx.

Перенаправление по IP или языку браузера

Если один и тот же адрес сразу отправляет робота на версию по IP, остальные версии он может не увидеть. Блог Bing (2009): «Having a contextual URL per language is necessary for ensuring the content is crawled». Для Google нужен отдельный URL на каждую версию.

Плагины и CMS

Тот же набор записывают дважды: плагин пишет hreflang в sitemap, а тема или второй плагин добавляет теги в head. Получаются дубли и конфликты. В CMS проверяйте, где разметку выводит каждый плагин, и оставляйте один способ.

Схема 3

Canonical и hreflang: куда ведёт canonical

французская страница, адреса условные
Правильно
/fr/canonical/fr/
<link rel="canonical" href="https://example.com/fr/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">

Страница сама себе canonical и перечисляет себя в hreflang.

Ошибка
/fr/canonical/en/
<link rel="canonical" href="https://example.com/en/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">

Французская страница называет главной английскую. Локализованная версия может свестись к чужой, а аннотации адреса, который не считается каноническим, по словам Мюллера, не используются.

Google просит указывать canonical на странице того же языка.

Таблица 4 собирает по этим и предыдущим разделам, что именно перестаёт работать при каждой ошибке, как её найти и как исправить.

Таблица: последствия ошибок hreflang, способ обнаружения и исправление
ОшибкаЧто перестаёт работатьМасштабКак найтиКак исправитьОснование
Неверный код в одной ссылкеЭта ссылка игнорируется, остальные работаютСсылка; если код в шаблоне, то язык на всём сайтеВалидатор, сверка с реестром IANAЗаменить по таблице 3сотрудник Google
Нет ссылки назадИгнорируется пара, остальные пары живыПараСверить набор ссылок на обеих страницах, валидаторДобавить возврат на каждой версиисправка Google
Нет самоссылкиНарушено правило справки; что именно Google отбрасывает, он не описываетСтраница, не подтвержденоВалидаторДобавить ссылку на саму страницусправка Google
head закрылся раньше времениАннотации страницы отбрасываются целикомСтраницаОтрисованный HTML: «Проверить URL → Просмотреть проверенную страницу»Убрать из начала head теги, которым место в body, или перенести скрипт нижесотрудник Google
Canonical ведёт на другой языкЛокализованная версия может свестись к чужойСтраницаСравнить canonical с адресом страницыCanonical на саму страницурекомендация Google
Hreflang на неканоническом адресеАннотации этого адреса не используютсяАдресСверить адреса из hreflang с canonical, убрать параметры и UTMУказывать канонический адрессотрудник Google
Альтернатива с noindexСтраница в кластер не попадает, кластер строится по остальным ссылкамСсылкаПроверить мета robots и заголовок ответа у каждой страницы кластераСнять noindex или убрать ссылку из наборасотрудник Google
Альтернатива отвечает редиректомПару не стоит считать исправной: возвратная ссылка с конечной страницы указывает на другой адресПараПроверить код ответа каждой альтернативыУказать в hreflang конечный адресвывод из правил
Связь между не-переводами«Probably worse than not having hreflang set up at all»КластерТолько вручную: валидатор смысл пары не видитСвязывать только версии одного содержимогосотрудник Google
Один код ведёт на разные адреса в HTML и sitemapGoogle «would probably just drop that pair»ПараСравнить наборы «код — адрес» в HTML и sitemapОдин способ или одинаковые наборысотрудник Google
Что не подтверждено

Я не нашёл подтверждения, как Google обрабатывает символ # в адресе hreflang, элемент xhtml:link вне url и hreflang, объявленный только в индексе sitemap. Эти случаи в таблице помечены «не подтверждено».

Таблица: 208 строк «неправильно → правильно»

В таблице собрано всё, что нашлось в документации Google, высказываниях сотрудников, исследованиях и справках инструментов: у каждой строки есть код неверного варианта, код правильного, оценка надёжности вывода и идентификаторы источников. Строки разбиты на девять групп. Каждая группа раскрывается в отдельную таблицу. Полный файл со всеми колонками (что говорят источники, какие инструменты ловят ошибку, серьёзность) можно скачать.

Скачать таблицу (CSV, 208 строк)

Как читать колонку «Надёжность»
  • Google напрямую — в документации или высказывании Google есть точная формулировка.
  • Заявление сотрудника — слова сотрудника Google (Мюллер, Иллис и другие), привязанные к дате.
  • Документация не Google — справки Яндекса и Bing, стандарты вроде RFC.
  • Вывод из правил — следует из стандартов и справки Google, но прямого утверждения нет.
  • Вторичный источник — описано в блоге или инструменте.
  • Не подтверждено — прямых источников нет; строка оставлена как описание ситуации.

Если у строки несколько меток, фильтр считает первую.

А. Код языка · 24
№ОшибкаНеправильноПравильноНадёжность
1Трёхбуквенный код языка вместо двухбуквенного (eng, rus, deu)
<link rel="alternate" hreflang="eng" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
Google напрямую
2Код страны вместо кода языка: jp для японского
<link rel="alternate" hreflang="jp" href="https://example.com/ja/">
<link rel="alternate" hreflang="ja" href="https://example.com/ja/">
(если нужен регион: <link rel="alternate" hreflang="ja-JP" href="https://example.com/ja/">)
вывод из правил
3Код страны вместо кода языка: cn для китайского
<link rel="alternate" hreflang="cn" href="https://example.com/zh/">
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh/">
(или по письменности: <link rel="alternate" hreflang="zh-Hans" href="https://example.com/zh/">)
вывод из правил
4kr для корейского (код канури)
<link rel="alternate" hreflang="kr" href="https://example.com/ko/">
<link rel="alternate" hreflang="ko" href="https://example.com/ko/">
вывод из правил
5se для шведского (код северносаамского)
<link rel="alternate" hreflang="se" href="https://example.com/sv/">
<link rel="alternate" hreflang="sv" href="https://example.com/sv/">
(или <link rel="alternate" hreflang="sv-SE" href="https://example.com/sv/">)
вывод из правил
6Коды стран dk, gr, cz вместо кодов языков
<link rel="alternate" hreflang="dk" href="https://example.com/da/">
<link rel="alternate" hreflang="gr" href="https://example.com/el/">
<link rel="alternate" hreflang="cz" href="https://example.com/cs/">
<link rel="alternate" hreflang="da-DK" href="https://example.com/da/">
<link rel="alternate" hreflang="el-GR" href="https://example.com/el/">
<link rel="alternate" hreflang="cs-CZ" href="https://example.com/cs/">
вывод из правил
7ua для украинского
<link rel="alternate" hreflang="ua" href="https://example.com/uk/">
<link rel="alternate" hreflang="uk" href="https://example.com/uk/">
(или <link rel="alternate" hreflang="uk-UA" href="https://example.com/uk/">; русский для Украины: <link rel="alternate" hreflang="ru-UA" href="https://example.com/ru-ua/">)
вывод из правил
8uk как «United Kingdom» в языковой позиции (uk — это украинский язык)
<link rel="alternate" hreflang="uk" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
вывод из правил
9Устаревший код иврита iw
<link rel="alternate" hreflang="iw" href="https://example.com/he/">
<link rel="alternate" hreflang="he" href="https://example.com/he/">
(или <link rel="alternate" hreflang="he-IL" href="https://example.com/he/">)
вывод из правил
10Устаревший код индонезийского in (одновременно IN — Индия)
<link rel="alternate" hreflang="in" href="https://example.com/id/">
<link rel="alternate" hreflang="id" href="https://example.com/id/">
(или <link rel="alternate" hreflang="id-ID" href="https://example.com/id/">)
вывод из правил
11Устаревший код идиша ji
<link rel="alternate" hreflang="ji" href="https://example.com/yi/">
<link rel="alternate" hreflang="yi" href="https://example.com/yi/">
вывод из правил
12Устаревшие коды jw (яванский) и mo (молдавский)
<link rel="alternate" hreflang="jw" href="https://example.com/jv/">
<link rel="alternate" hreflang="mo" href="https://example.com/ro-md/">
<link rel="alternate" hreflang="jv" href="https://example.com/jv/">
<link rel="alternate" hreflang="ro-MD" href="https://example.com/ro-md/">
вывод из правил
13no-NO вместо более точного nb-NO / nn-NO (нормативно это не ошибка)
<link rel="alternate" hreflang="no-NO" href="https://example.com/no/">
<link rel="alternate" hreflang="nb-NO" href="https://example.com/no/">
(допустимо и <link rel="alternate" hreflang="no" href="https://example.com/no/">)
вывод из правил
14fil вместо tl для филиппинского
<link rel="alternate" hreflang="fil" href="https://example.com/tl/">
<link rel="alternate" hreflang="tl" href="https://example.com/tl/">
Google напрямую
15Опечатка в коде языка (fl вместо tl)
<xhtml:link rel="alternate" hreflang="fl" href="https://example.com/tl/"/>
<xhtml:link rel="alternate" hreflang="tl" href="https://example.com/tl/"/>
вторичный источник
16Опечатка превращает код в другой валидный язык (fi вместо fr)
<link rel="alternate" hreflang="fi" href="https://example.com/fr/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
вторичный источник
17cr вместо hr для хорватского
<link rel="alternate" hreflang="cr" href="https://example.com/hr/">
<link rel="alternate" hreflang="hr" href="https://example.com/hr/">
вторичный источник
18sh (сербохорватский) вместо sr, hr или bs
<link rel="alternate" hreflang="sh" href="https://example.com/sr/">
<link rel="alternate" hreflang="sr" href="https://example.com/sr/">
(или <link rel="alternate" hreflang="hr" href="https://example.com/hr/">, <link rel="alternate" hreflang="bs" href="https://example.com/bs/"> по содержанию)
вывод из правил
19la как «Латинская Америка»
<link rel="alternate" hreflang="la" href="https://example.com/es/">
<link rel="alternate" hreflang="es" href="https://example.com/es/">
(или по странам: <link rel="alternate" hreflang="es-MX" href="https://example.com/es-mx/">, <link rel="alternate" hreflang="es-AR" href="https://example.com/es-ar/">)
вторичный источник
20Язык в hreflang не совпадает с языком контента (французский тег на английской странице)
<link rel="alternate" hreflang="fr" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
вторичный источник
21Несовпадение html lang и hreflang
<html lang="fr">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
<html lang="de">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
вторичный источник
22Язык вне списка из 40 языков Яндекса в расчёте на Яндекс (zh, ja, ko, hi, th, id, vi и др.)
<link rel="alternate" hreflang="ja" href="https://example.com/ja/">
Яндекс перечисляет 40 двухбуквенных языков ISO 639-1; для языков вне списка эффект в справке не описан.
официальная документация (не Google)
23Реестр IANA пропускает 7 двухбуквенных кодов, которых нет среди 183 актуальных кодов ISO 639-1 (bh, in, iw, ji, jw, mo, sh)
<link rel="alternate" hreflang="iw" href="https://example.com/he/">
<link rel="alternate" hreflang="in" href="https://example.com/id/">
<link rel="alternate" hreflang="he" href="https://example.com/he/">
<link rel="alternate" hreflang="id" href="https://example.com/id/">
вывод из правил
24Валидный по BCP 47 тег с языком вне ISO 639-1 (fil-PH, kok-IN, prs-AF, quz-BO)
<link rel="alternate" hreflang="kok-IN" href="https://example.com/kok/">
<link rel="alternate" hreflang="fil-PH" href="https://example.com/fil/">
<link rel="alternate" hreflang="tl-PH" href="https://example.com/tl/">
(для kok и prs кода ISO 639-1 нет; ближайшая замена в базе не названа)
вывод из правил
Б. Код региона · 22
№ОшибкаНеправильноПравильноНадёжность
25en-UK вместо en-GB
<link rel="alternate" hreflang="en-UK" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
Google напрямую
26EU как регион (en-EU, es-eu): континенты Google не поддерживает
<link rel="alternate" hreflang="en-EU" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
(или список стран: <link rel="alternate" hreflang="en-IE" href="https://example.com/en-ie/">, <link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">)
Google напрямую
27UN как регион или одиночное значение
<link rel="alternate" hreflang="UN" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
Google напрямую
28Придуманные «рыночные» коды (EU, APAC) вместо ISO
<link rel="alternate" hreflang="APAC" href="https://example.com/en-apac/">
<link rel="alternate" hreflang="en-AU" href="https://example.com/en-au/">
(страны по отдельности, ISO 3166-1 Alpha 2)
вторичный источник
29es-419 (Латинская Америка, UN M.49)
<link rel="alternate" hreflang="es-419" href="https://example.com/es-latam/">
<link rel="alternate" hreflang="es" href="https://example.com/es/">
(или по странам: <link rel="alternate" hreflang="es-MX" href="https://example.com/es-mx/">, <link rel="alternate" hreflang="es-AR" href="https://example.com/es-ar/">)
Google напрямую
30es-LA для «Латинской Америки» (LA — Лаос)
<link rel="alternate" hreflang="es-LA" href="https://example.com/es-latam/">
<link rel="alternate" hreflang="es" href="https://example.com/es/">
(или по странам: <link rel="alternate" hreflang="es-CO" href="https://example.com/es-co/">, <link rel="alternate" hreflang="es-MX" href="https://example.com/es-mx/">)
официальное заявление сотрудника
31Только страна, без языка (US, GB)
<link rel="alternate" hreflang="US" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
Google напрямую
32be для Бельгии (be — белорусский язык)
<link rel="alternate" hreflang="be" href="https://example.com/be/">
<link rel="alternate" hreflang="nl-BE" href="https://example.com/nl-be/">
<link rel="alternate" hreflang="fr-BE" href="https://example.com/fr-be/">
<link rel="alternate" hreflang="de-BE" href="https://example.com/de-be/">
Google напрямую
33Одиночные коды страны ca, br, ch, us вместо язык-регион
<link rel="alternate" hreflang="ca" href="https://example.com/en-ca/">
<link rel="alternate" hreflang="br" href="https://example.com/pt-br/">
<link rel="alternate" hreflang="ch" href="https://example.com/de-ch/">
<link rel="alternate" hreflang="en-CA" href="https://example.com/en-ca/">
<link rel="alternate" hreflang="pt-BR" href="https://example.com/pt-br/">
<link rel="alternate" hreflang="de-CH" href="https://example.com/de-ch/">
вывод из правил
34Обратный порядок: регион перед языком (GB-en, US-en)
<link rel="alternate" hreflang="GB-en" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
вторичный источник
35Трёхбуквенная страна вместо двухбуквенной (en-USA, ru-RUS)
<link rel="alternate" hreflang="en-USA" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
вывод из правил
36Перепутаны URL для pt-PT и pt-BR (оба кода валидны)
<link rel="alternate" hreflang="pt-PT" href="https://example.com/pt-br/">
<link rel="alternate" hreflang="pt-BR" href="https://example.com/pt-pt/">
<link rel="alternate" hreflang="pt-PT" href="https://example.com/pt-pt/">
<link rel="alternate" hreflang="pt-BR" href="https://example.com/pt-br/">
вывод из правил
37Перепутаны язык и страна в значении (en-DE для немецкой версии вместо de-DE)
<link rel="alternate" hreflang="en-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
вывод из правил
38Необычные пары язык-регион без реального контента под них
<link rel="alternate" hreflang="zh-ZM" href="https://example.com/zh-zm/">
оставить версии, под которые есть отдельный контент; для остальных использовать общий язык
вторичный источник
39zh-TW / zh-tw считают ошибкой (это допустимо, письменность выводится из страны)
<link rel="alternate" hreflang="zh-tw" href="https://example.com/zh-tw/">
<link rel="alternate" hreflang="zh-TW" href="https://example.com/zh-tw/">
(или явно: <link rel="alternate" hreflang="zh-Hant" href="https://example.com/zh-tw/">)
Google напрямую
40Устаревшие обозначения письменности zh-CHS и zh-CHT
<link rel="alternate" hreflang="zh-CHS" href="https://example.com/zh-cn/">
<link rel="alternate" hreflang="zh-CHT" href="https://example.com/zh-tw/">
<link rel="alternate" hreflang="zh-Hans" href="https://example.com/zh-cn/">
<link rel="alternate" hreflang="zh-Hant" href="https://example.com/zh-tw/">
вывод из правил
41Лишний скрипт у языка с единственной письменностью (en-Latn, ru-Cyrl)
<link rel="alternate" hreflang="en-Latn" href="https://example.com/en/">
<link rel="alternate" hreflang="ru-Cyrl" href="https://example.com/ru/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
вывод из правил
42sr-Latn считают ошибкой (корректный тег, но поддержка у Google прямо не подтверждена)
<link rel="alternate" hreflang="sr-Latn" href="https://example.com/sr-latn/">
оставить; при сомнении проверять поведение на своих страницах
не подтверждено
43Швейцарский немецкий gsw-CH вместо de-CH (поддержка gsw у Google не подтверждена)
<link rel="alternate" hreflang="gsw-CH" href="https://example.com/de-ch/">
<link rel="alternate" hreflang="de-CH" href="https://example.com/de-ch/">
вывод из правил
44Регион для Яндекса по ISO 3166-2:RU в расчёте на Google
hreflang="ru" + код региона РФ по ISO 3166-2:RU (формат записи в справке Яндекса в базе не приведён)
для Google: только ISO 3166-1 Alpha 2 (например <link rel="alternate" hreflang="ru-RU" href="https://example.com/ru/">)
вывод из правил
45de или de-DE: считают обязательным указывать регион
<link rel="alternate" hreflang="de" href="https://example.com/de/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(если нужна привязка к стране: <link rel="alternate" hreflang="de-DE" href="https://example.com/de/">)
официальное заявление сотрудника
46Подрегион по ISO 3166-2 вместо страны (en-US-CA)
<link rel="alternate" hreflang="en-US-CA" href="https://example.com/en-us-ca/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
официальное заявление сотрудника
В. Формат и регистр · 8
№ОшибкаНеправильноПравильноНадёжность
47Подчёркивание вместо дефиса (en_US, de_DE)
<link rel="alternate" hreflang="en_US" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
вторичный источник
48Регистр считают значимым (en-us, EN-gb, X-Default): для Google он ничего не меняет
<link rel="alternate" hreflang="en-us" href="https://example.com/en-us/">
<link rel="alternate" hreflang="EN-gb" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="X-Default" href="https://example.com/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
Google напрямую
49Пробелы внутри значения hreflang
<link rel="alternate" hreflang=" en-GB " href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
не подтверждено
50Лишние дефисы и пустые подтеги (en--GB, en-GB-)
<link rel="alternate" hreflang="en--GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB-" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
не подтверждено
51Пустое значение hreflang или href
<link rel="alternate" hreflang="" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
не подтверждено
52Язык добавлен к x-default (x-default-en, en-x-default)
<link rel="alternate" hreflang="x-default-en" href="https://example.com/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
Google напрямую
53Считают ошибкой hreflang без кавычек в заголовке Link
Link: <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang=ru
Link: <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
официальная документация (не Google)
54Несколько значений через пробел в одном атрибуте hreflang
<link rel="alternate" hreflang="de-DE de-AT" href="https://example.com/de/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de/">
<link rel="alternate" hreflang="de-AT" href="https://example.com/de/">
вывод из правил
Г. Структура кластера · 28
№ОшибкаНеправильноПравильноНадёжность
55Нет обратной ссылки (return tag): A ссылается на B, B на A не ссылается
<!-- https://example.com/en/ -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<!-- https://example.com/de-de/ : ссылки на en нет -->
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<!-- на обеих страницах один и тот же набор -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
Google напрямую
56Нет обратной ссылки и неполный набор в заголовке Link у PDF
<!-- manual-en.pdf -->
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
<!-- manual-de.pdf -->
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE"
<!-- у каждого файла один и тот же набор, включая сам файл -->
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
Google напрямую
57Нет обратной ссылки в sitemap: запись одной версии не перечисляет другую
<url>
<loc>https://example.com/en/blog/hello/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/blog/hello/"/>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/privet/"/>
</url>
<url>
<loc>https://example.com/ru/blog/privet/</loc>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/privet/"/>
</url>
<!-- в обоих <url> одинаковый набор из двух xhtml:link -->
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/blog/hello/"/>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/privet/"/>
Google напрямую
58Нет самоссылки: страница не перечисляет саму себя
<!-- https://example.com/en-gb/ -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
Google напрямую
59Нет самоссылки в sitemap: запись не содержит xhtml:link на свой же URL
<url>
<loc>https://example.com/ru/produkty/widget/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/products/widget/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/produkte/widget/"/>
</url>
<url>
<loc>https://example.com/ru/produkty/widget/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/products/widget/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/produkte/widget/"/>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/produkty/widget/"/>
</url>
Google напрямую
60Повтор одного и того же значения на один и тот же URL
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
не подтверждено
61Два разных URL на одно значение hreflang
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
официальное заявление сотрудника
62Один URL указан под двумя разными языками
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
вторичный источник
63Один и тот же язык/регион указан для разных страниц разными способами (HTML и sitemap)
<!-- в HTML страницы https://example.com/en/ -->
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
<!-- в sitemap для той же страницы -->
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru-new/"/>
один источник разметки на кластер
официальное заявление сотрудника
64Несколько x-default на одну страницу или кластер
<link rel="alternate" hreflang="x-default" href="https://example.com/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
официальное заявление сотрудника
65x-default на главную, которая редиректит по языку или IP (одни источники называют ошибкой, Google допускает)
<link rel="alternate" hreflang="x-default" href="https://example.com/">
<!-- https://example.com/ отвечает 302 на /en/ или /de-de/ -->
тот же x-default, при условии что языковые страницы открываются без редиректа
Google напрямую
66x-default на страницу другого языка или не на селектор считают ошибкой
<link rel="alternate" hreflang="x-default" href="https://example.com/de-de/">
допустимо: любая страница, которую вы считаете запасной, например <link rel="alternate" hreflang="x-default" href="https://example.com/en/">
Google напрямую
67Нет x-default (считают обязательным)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
(добавить к набору выше, если нужна запасная страница)
Google напрямую
68Корень "/" редиректит по гео или языку, но не объявлен x-default
<link rel="alternate" hreflang="en-US" href="https://example.com/us/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/">
<!-- "/" редиректит на /us/ или /uk/ и в наборе не указан -->
<link rel="alternate" hreflang="x-default" href="https://example.com/">
(плюс набор стран)
официальное заявление сотрудника
69x-default без полного кластера языковых версий
<link rel="alternate" hreflang="x-default" href="https://example.com/en/">
<!-- других языковых <link> на странице нет -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/">
официальное заявление сотрудника
70Разные наборы hreflang на разных версиях страницы
<!-- https://example.com/en/ -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
<!-- https://example.com/de-de/ : ru пропущен -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
на каждой версии идентичный набор из всех существующих версий
Google напрямую
71Нет «общей» страницы языка рядом с региональными
<link rel="alternate" hreflang="en-IE" href="https://example.com/en-ie/">
<link rel="alternate" hreflang="en-CA" href="https://example.com/en-ca/">
<link rel="alternate" hreflang="en-AU" href="https://example.com/en-au/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
(добавить к набору; может быть одной из региональных страниц)
Google напрямую
72Новая языковая версия не связана двусторонне с исходной
<!-- https://example.com/fr/ ссылается на en, а https://example.com/en/ на fr не ссылается -->
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<!-- на обеих страницах -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
Google напрямую
73В кластер включена ссылка на несуществующий перевод
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/blog/hello/">
<!-- страницы по этому адресу нет или она отдаёт 404 -->
убрать ссылку на несуществующую версию из набора
вторичный источник
74Конфликтные входящие аннотации: другая страница называет тот же URL другим языком
<!-- на https://example.com/en/ -->
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
<!-- на https://example.com/de-de/ -->
<link rel="alternate" hreflang="es" href="https://example.com/fr/">
один и тот же код для одного URL на всех страницах кластера
вторичный источник
75Несколько самоссылок с разными значениями (en и en-US на себя же)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en/">
одна самоссылка, например <link rel="alternate" hreflang="en" href="https://example.com/en/">
вторичный источник
76hreflang не на каждой странице считают ошибкой (хотя Google разрешает частичное покрытие)
hreflang только на главных страницах кластера, на внутренних его нет
допустимо: размечать постранично, прежде всего страницы, которые путаются
Google напрямую
77Кластер из одной страницы: hreflang на сайте с единственной языковой версией
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<!-- других версий нет -->
убрать разметку, пока нет второй версии
официальное заявление сотрудника
78Hreflang связывает страницы, не являющиеся переводами друг друга (английская «Fish» и испанская «Chicken»)
(на https://example.com/en/fish/)
<link rel="alternate" hreflang="es" href="https://example.com/es/pollo/">
<link rel="alternate" hreflang="en" href="https://example.com/en/fish/">
<link rel="alternate" hreflang="es" href="https://example.com/es/pescado/">
<link rel="alternate" hreflang="en" href="https://example.com/en/fish/">
официальное заявление сотрудника
79x-default указывает на страницу, не равную текущей по смыслу (товар ведёт на главную; свой x-default у каждого региона)
(на https://example.com/pt-pt/temperos/)
<link rel="alternate" hreflang="x-default" href="https://example.com/">
(на https://example.com/pt-lu/temperos/)
<link rel="alternate" hreflang="x-default" href="https://example.com/pt-lu/">
<link rel="alternate" hreflang="x-default" href="https://example.com/temperos/">
(одна и та же страница x-default во всех версиях кластера)
официальное заявление сотрудника
80В набор включена версия, у которой ещё нет контента (/pl/ без страниц)
<link rel="alternate" hreflang="pl" href="https://example.com/pl/">
(страница /pl/ пуста или отдаёт 404, ссылка на неё стоит на всех версиях)
(строку pl убрать на всех версиях, пока перевода нет)
официальное заявление сотрудника
81У страницы нет собственного адреса для проверки: ни canonical, ни метки URL
<link rel="alternate" hreflang="en" href="https://example.com/en/x/">
(в <head> нет rel="canonical"; страница проверяется как отдельный файл)
<link rel="canonical" href="https://example.com/en/x/">
<link rel="alternate" hreflang="en" href="https://example.com/en/x/">
вывод из правил
82Адрес страницы известен проверке только по rel=canonical, метки адреса в файле нет
<link rel="canonical" href="https://example.com/en/y/">
<link rel="alternate" hreflang="en" href="https://example.com/en/y/">
(комментария-метки адреса страницы в файле нет)
(при проверке файлов указывать адрес страницы меткой-комментарием, а живые страницы проверять по их URL)
вывод из правил
Д. URL в аннотации · 19
№ОшибкаНеправильноПравильноНадёжность
83Относительный URL в hreflang (/de-de/ вместо полного адреса)
<link rel="alternate" hreflang="de-DE" href="/de-de/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
Google напрямую
84URL без схемы (protocol-relative) в hreflang или в <loc>
<link rel="alternate" hreflang="de-DE" href="//example.com/de-de/">
<loc>//example.com/en/catalog/</loc>
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
Google напрямую
85В hreflang и sitemap указан HTTP-адрес, когда каноническая версия на HTTPS
<link rel="alternate" hreflang="en" href="http://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
Google напрямую
86Адрес в hreflang отличается от канонического слэшем (/de-de вместо /de-de/)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de">
(страница отвечает по адресу https://example.com/de-de/, версия без слэша редиректит)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
вывод из правил
87Альтернативный URL в hreflang отдаёт редирект (3xx)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de-old/">
(адрес /de-de-old/ отвечает 301 на /de-de/)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
вторичный источник
88Альтернативный URL отдаёт 404 или 5xx
<link rel="alternate" hreflang="fr-FR" href="https://example.com/fr-fr/deleted/">
(адрес /fr-fr/deleted/ отвечает 404)
убрать запись из набора на всех версиях либо вернуть страницу с ответом 200
вторичный источник
89Альтернативная страница закрыта noindex
<meta name="robots" content="noindex">
(стоит на /de-de/, а <link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"> есть на /en/)
убрать noindex со страниц кластера либо убрать такие страницы из набора на всех версиях
официальное заявление сотрудника
90Альтернативная страница закрыта в robots.txt
User-agent: *
Disallow: /de-de/
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
открыть /de-de/ для краулера (robots.txt и meta robots должны одинаково работать во всех локалях)
вторичный источник
91В hreflang указан URL, у которого canonical ведёт на другой адрес
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="canonical" href="https://example.com/en-us/">
(canonical стоит на странице /en-gb/)
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="canonical" href="https://example.com/en-gb/">
Google напрямую
92Canonical всех языковых версий указывает на одну (английскую) страницу
<link rel="canonical" href="https://example.com/en/">
(стоит на странице /de-de/)
<link rel="canonical" href="https://example.com/de-de/">
Google напрямую
93Canonical для одной страницы задан в sitemap и в rel=canonical разными адресами
<loc>https://example.com/de-de/</loc>
<link rel="canonical" href="https://example.com/de-de/?ref=nav">
(первое в sitemap, второе на самой странице)
<loc>https://example.com/de-de/</loc>
<link rel="canonical" href="https://example.com/de-de/">
Google напрямую
94В hreflang-адрес попали параметры, которых нет в canonical
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/?setContextLanguageCode=en-us">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
официальное заявление сотрудника
95Кириллица в адресе без процентного кодирования
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/привет/"/>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82/"/>
Google напрямую
96Языковая версия через параметр URL (?loc=de) вместо отдельного пути
<link rel="alternate" hreflang="de" href="https://example.com/?loc=de">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
Google напрямую
97Языковой поддомен считают самодостаточным сигналом аудитории
<link rel="alternate" hreflang="de" href="https://de.example.com/">
(у en.example.com и de.example.com нет hreflang друг на друга)
<link rel="alternate" hreflang="en" href="https://en.example.com/">
<link rel="alternate" hreflang="de" href="https://de.example.com/">
(оба тега на каждой из двух версий)
Google напрямую
98Аннотации страницы ведут на главные страницы языков вместо соответствующих страниц
<link rel="alternate" hreflang="en" href="https://example.com/en/blog/hello/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
(набор на странице /en/blog/hello/)
<link rel="alternate" hreflang="en" href="https://example.com/en/blog/hello/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/blog/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82/">
Google напрямую
99Считают, что одна noindex-страница в кластере выключает hreflang у остальных версий
(на https://example.com/de-de/)
<meta name="robots" content="noindex">
(на /en/, /ru/ и /fr/ ссылка hreflang на /de-de/ остаётся)
(убрать noindex со страницы либо убрать её из набора на всех версиях; остальные версии работают без неё)
официальное заявление сотрудника
100hreflang стоит на неканоническом URL (дубль с параметрами или другой вариант адреса)
(на https://example.com/de-de/?utm_source=a, canonical ведёт на /de-de/)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/?utm_source=a">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
официальное заявление сотрудника
101Отдельные мобильные URL: hreflang мобильной версии ведёт на десктопные адреса
(на https://m.example.com/de/)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://m.example.com/en/">
(на десктопных URL hreflang остаётся на десктопных)
Google напрямую
Е. Размещение и синтаксис · 39
№ОшибкаНеправильноПравильноНадёжность
102Теги hreflang оказались в <body> (head закрылся раньше)
<head><title>Home</title></head>
<body>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
<head>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
</head>
Google напрямую
103Тег или скрипт в <head> до hreflang закрывает head, и ссылки уходят в body
<head>
<iframe src="https://example.com/widget/"></iframe>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
<head>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
(сторонние виджеты и скрипты после hreflang или в body)
вторичный источник
104hreflang объединён с media в одном <link>
<link rel="alternate" hreflang="de-DE" media="only screen and (max-width: 640px)" href="https://example.com/de-de/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
Google напрямую
105hreflang на ссылке <a>, а не на <link>
<a rel="alternate" hreflang="de" href="https://example.com/de/">Deutsch</a>
<link rel="alternate" hreflang="de" href="https://example.com/de/">
официальное заявление сотрудника
106rel="canonical" с атрибутом hreflang вместо rel="alternate"
<link rel="canonical" hreflang="de" href="https://example.com/de-de/">
<link rel="alternate" hreflang="de" href="https://example.com/de-de/">
Google напрямую
107hreflang добавляется скриптом после загрузки (JS, GTM), а не лежит в исходном HTML
<script>var l=document.createElement('link');l.rel='alternate';l.hreflang='de';l.href='https://example.com/de/';document.head.appendChild(l);</script>
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(в исходном HTML ответа либо в HTTP-заголовке)
вторичный источник
108Все три способа включены одновременно (HTML, заголовок, sitemap)
<link rel="alternate" hreflang="de" href="https://example.com/de/">
Link: <https://example.com/de/>; rel="alternate"; hreflang="de"
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/"/>
(один и тот же набор в head, в заголовке и в sitemap)
выбрать один способ, например sitemap или HTML
Google напрямую
109Content-Language или meta content-language вместо hreflang
Content-Language: de
<meta http-equiv="content-language" content="de">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(язык страницы Google берёт из видимого текста)
официальное заявление сотрудника
110URL в заголовке Link без угловых скобок
Link: https://example.com/files/manual-ru.pdf; rel="alternate"; hreflang="ru"
Link: <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
Google напрямую
111В заголовке Link нет rel="alternate"
Link: <https://example.com/files/manual-de.pdf>; hreflang="de"
Link: <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de"
Google напрямую
112Относительный URL в заголовке Link
Link: </files/manual-de.pdf>; rel="alternate"; hreflang="de"
Link: <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de"
Google напрямую
113Hreflang-набор разнесён по нескольким строкам Link:
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en"
Link: <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE"
Link: <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
не подтверждено
114В <urlset> не объявлено пространство имён xhtml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/"/>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
Google напрямую
115Опечатка в адресе пространства имён xhtml
xmlns:xhtml="http://www.w3.org/1999/xhtm"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
вывод из правил
116Неверное пространство имён корня sitemap (sitemap/0.84 вместо 0.9)
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.84" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
вывод из правил
117Sitemap не в UTF-8 (декларация ISO-8859-1 или байты Latin-1)
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml version="1.0" encoding="UTF-8"?>
Google напрямую
118Не экранирован & в <loc> и в href
<loc>https://example.com/en/catalog/?color=red&size=m</loc>
<loc>https://example.com/en/catalog/?color=red&amp;size=m</loc>
Google напрямую
119Sitemap не well-formed (незакрытый <url>)
<url>
<loc>https://example.com/en/</loc>
(нет </url>)
<url>
<loc>https://example.com/en/</loc>
</url>
вывод из правил
120Превышен лимит одного sitemap (50 000 URL или 50 МБ) без деления на файлы
один sitemap.xml на 60 000 элементов <url>
несколько sitemap-файлов и sitemap index
Google напрямую
121Дочерние xhtml:link считают в лимит 50 000 URL
sitemap делят на файлы по 12 000 <url> из-за четырёх xhtml:link в каждой записи
в лимит идут только элементы <url>; дочерние xhtml:link не считаются
Google напрямую
122Sitemap лежит в подпапке, а перечисляет адреса из других папок
https://example.com/de-de/sitemap.xml
<loc>https://example.com/en/about/</loc>
(адрес sitemap и запись в нём)
sitemap в корне сайта (или отправка через Search Console или robots.txt для нескольких сайтов)
Google напрямую
123В одном sitemap адреса с разных хостов без cross-submit
<loc>https://example.com/en/</loc>
<loc>https://shop.example.com/de/</loc>
(оба в одном файле)
по одному sitemap на хост либо cross-submit между верифицированными сайтами
Google напрямую
124В sitemap xhtml:link с rel="canonical" вместо rel="alternate"
<xhtml:link rel="canonical" hreflang="de" href="https://example.com/de-de/"/>
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de-de/"/>
вывод из правил
125xhtml:link без атрибута hreflang
<xhtml:link rel="alternate" href="https://example.com/de-de/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"/>
вывод из правил
126Два элемента <url> с одним и тем же <loc>
<url><loc>https://example.com/en/blog/hello/</loc> ... </url>
<url><loc>https://example.com/en/blog/hello/</loc> ... </url>
(запись повторена дважды)
один <url> на один адрес с полным набором xhtml:link
вывод из правил
127priority и changefreq в расчёте на влияние; lastmod обновляют у одной версии в расчёте на пере-обход набора
<url><loc>https://example.com/en/</loc><lastmod>2026-10-19</lastmod><priority>1.0</priority><changefreq>daily</changefreq></url>
<url><loc>https://example.com/en/</loc><lastmod>2026-10-19</lastmod></url>
(lastmod только точный, без priority и changefreq)
Google напрямую
128lastmod в sitemap index не в формате W3C Datetime
<lastmod>01.10.2026</lastmod>
<lastmod>2026-10-01</lastmod>
Google напрямую
129Sitemap index ссылается на файл, которого нет, или <sitemap> без <loc>
<sitemap><loc>https://example.com/sitemap-missing.xml</loc></sitemap>
<sitemap><lastmod>2026-10-01</lastmod></sitemap>
<sitemap><loc>https://example.com/sitemap-zh.xml</loc><lastmod>2026-10-01</lastmod></sitemap>
вывод из правил
130Sitemap с hreflang не заявлен в Search Console и robots.txt
robots.txt без строки Sitemap
(sitemap доступен только по ping-запросу)
Sitemap: https://example.com/sitemap_index.xml
(и отправка в Search Console)
вторичный источник
131Считают, что записи одного кластера нельзя делить между файлами sitemap
sitemap-1.xml: записи для /en/widget/ и /de-de/widget/
sitemap-2.xml: записи для /ru/widget/ и x-default
(кластер разнесён по двум файлам, это считают ошибкой)
допустимы оба варианта, выбирают тот, который проще вести
официальное заявление сотрудника
132hreflang размещают только в sitemap в расчёте на Яндекс
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/"/>
(разметки в head нет, hreflang лежит только в sitemap)
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
(на каждой версии страницы, в head)
официальная документация (не Google)
133<noscript> с iframe в <head> выше hreflang: head закрывается раньше, ссылки уходят в body
<head>
<title>Widget</title>
<noscript><iframe src="https://example.com/tag-frame.html" height="0" width="0"></iframe></noscript>
<link rel="alternate" hreflang="en" href="https://example.com/en/">
</head>
<head>
<link rel="canonical" href="https://example.com/en/">
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<title>Widget</title>
<noscript><iframe src="https://example.com/tag-frame.html" height="0" width="0"></iframe></noscript>
</head>
Google напрямую
134Файл sitemap с hreflang упирается в 50 МБ раньше, чем в 50 000 URL
<url><loc>https://example.com/en/p1/</loc> + 30 строк <xhtml:link .../> </url>, повторено 50 000 раз в одном файле (пример гипотетический)
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap><loc>https://example.com/sitemap-products-1.xml</loc></sitemap>
<sitemap><loc>https://example.com/sitemap-products-2.xml</loc></sitemap>
Google напрямую
135xhtml:link стоит вне элемента <url>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"/>
<url><loc>https://example.com/en/</loc></url>
</urlset>
<url>
<loc>https://example.com/en/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"/>
</url>
не подтверждено
136hreflang размещён только в sitemap index
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<sitemap><loc>https://example.com/sitemap-en.xml</loc>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/sitemap-de.xml"/>
</sitemap></sitemapindex>
<sitemap><loc>https://example.com/sitemap-en.xml</loc></sitemap>
(аннотации лежат в элементах <url> внутри самих файлов sitemap, а индекс только перечисляет файлы)
не подтверждено
137Фрагмент (#…) в адресе значения hreflang
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/#catalog">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
не подтверждено
138<url> без <loc>
<url>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"/>
</url>
<url>
<loc>https://example.com/en/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/"/>
<xhtml:link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/"/>
</url>
вывод из правил
139hreflang прописывают в robots.txt
User-agent: *
Disallow:
    hreflang: de-DE https://example.com/de-de/
Sitemap: https://example.com/sitemap-hreflang.xml
(сам hreflang — в <head>, заголовке Link или sitemap; в robots.txt допустима строка Sitemap:)
вывод из правил
140Набор Link у одной версии PDF отличается от остальных
(https://example.com/files/manual-en.pdf)
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
(https://example.com/files/manual-de.pdf)
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
(во всех трёх ответах один набор из трёх версий)
Link: <https://example.com/files/manual-en.pdf>; rel="alternate"; hreflang="en", <https://example.com/files/manual-de.pdf>; rel="alternate"; hreflang="de-DE", <https://example.com/files/manual-ru.pdf>; rel="alternate"; hreflang="ru"
Google напрямую
Ж. CMS и сборки · 34
№ОшибкаНеправильноПравильноНадёжность
141Ждут hreflang от SEO-плагина без плагина-переводчика (Yoast SEO, Rank Math)
<head>
(в коде страницы нет ни одного <link rel="alternate" hreflang>)
<head>
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(набор выводит мультиязычный плагин, например WPML или Polylang)
официальная документация (не Google)
142Ищут hreflang от WPML в head, а он по умолчанию записан в XML-sitemap
(в исходном коде страницы нет <link rel="alternate" hreflang>)
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/"/>
(запись в XML-sitemap WPML, смотреть исходник XML, а не человекочитаемый вид в браузере)
вторичный источник
143Включили вывод hreflang в head (WPML) и не отключили вывод в sitemap
<link rel="alternate" hreflang="de" href="https://example.com/de/">
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/"/>
(один и тот же набор и в head, и в XML-sitemap)
define( 'WPML_SEO_ENABLE_SITEMAP_HREFLANG', false );
(строка в wp-config.php, hreflang остаётся только в head)
вторичный источник
144Shopify: свои hreflang-теги поверх автоматических
<link rel="alternate" hreflang="fr-FR" href="https://example.com/fr-fr/">
(набор вписан вручную в theme.liquid при включённых автотегах Markets)
либо удалить свои теги и оставить автоматические, либо отключить автотеги в Online store > Preferences и вести набор самим
официальная документация (не Google)
145Shopify: домены и handle товара прописаны в теме вручную
<link rel="alternate" hreflang="de" href="https://example.com/de/products/widget">
(адрес собран из захардкоженного домена и handle в theme.liquid)
(теги строятся из объекта localization; каждый локализованный URL ссылается на себя как canonical)
официальная документация (не Google)
146Shopify: ждут hreflang для рынка без отдельного домена, поддомена или подпапки
(рынок отдаёт ту же страницу по тому же URL, hreflang для него не создаётся)
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
(отдельная подпапка рынка; x-default указывает на основной домен)
официальная документация (не Google)
147Next.js: относительные пути в alternates.languages без metadataBase
export const metadata = { alternates: { languages: { 'en-US': '/en-us', 'de-DE': '/de-de' } } };
export const metadata = { metadataBase: new URL('https://example.com'), alternates: { languages: { 'en-US': '/en-us', 'de-DE': '/de-de' } } };
официальная документация (не Google)
148Next.js: одинаковый набор alternates.languages задан в общем layout для всех страниц
// layout.js
export const metadata = { metadataBase: new URL('https://example.com'), alternates: { languages: { en: '/en', de: '/de' } } };
(каждая страница получает hreflang на главные страницы языков)
// page.js
export async function generateMetadata() { return { alternates: { languages: { en: '/en/blog/hello/', ru: '/ru/blog/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82/' } } }; }
вывод из правил
149Nuxt i18n: не заданы language у локалей и baseUrl с продакшн-доменом
i18n: { locales: [{ code: 'en' }, { code: 'de' }] }
i18n: { baseUrl: 'https://example.com', locales: [{ code: 'en', language: 'en-US' }, { code: 'de', language: 'de-DE' }] }
официальная документация (не Google)
150Nuxt i18n: не учитывают автоматическую «catchall»-ссылку для группы локалей (en-*)
locales: [{ code: 'en-gb', language: 'en-GB' }, { code: 'en-us', language: 'en-US' }]
(первая объявленная локаль автоматически становится общим en)
locales: [{ code: 'en-gb', language: 'en-GB' }, { code: 'en-us', language: 'en-US', isCatchallLocale: true }]
официальная документация (не Google)
151Django: sitemap без i18n=True и alternates=True (или без x_default)
class PageSitemap(Sitemap):
    alternates = True
class PageSitemap(Sitemap):
    i18n = True
    alternates = True
    x_default = True
официальная документация (не Google)
152Django: x-default строится без языкового префикса, а такой URL не отдаёт страницу
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about/"/>
(адрес /about/ отвечает 404 или редиректит)
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about/"/>
(адрес /about/ отвечает 200 и является страницей по умолчанию)
вывод из правил
153Laravel (spatie/laravel-sitemap): добавлены только «чужие» языки без самоссылки
Url::create('https://example.com/extra-page')
    ->addAlternate('https://example.com/nl/extra-page', 'nl')
    ->addAlternate('https://example.com/fr/extra-page', 'fr')
Url::create('https://example.com/extra-page')
    ->addAlternate('https://example.com/extra-page', 'en')
    ->addAlternate('https://example.com/nl/extra-page', 'nl')
    ->addAlternate('https://example.com/fr/extra-page', 'fr')
вывод из правил
154Joomla: не заполнены Associations, поэтому hreflang не выводится
(у пунктов меню нет связанных пунктов на других языках)
(в head нет ни одного <link rel="alternate" hreflang>)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(при заполненных Associations и включённой опции «Add Alternate Meta Tags» плагина System - Language Filter)
официальная документация (не Google)
155Tilda: переключатель языков есть, hreflang не вставлен
(в блоках меню ссылки на /en и /es, поле «HTML-код для HEAD» пусто)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="es" href="https://example.com/es/">
(код вставлен в Page Settings → Additional → HTML code for the HEAD каждой страницы всех версий)
официальная документация (не Google)
1561С-Битрикс: один тег на страницу без самоссылки и обратных ссылок
<link rel="alternate" hreflang="en" href="https://example.com/en/page/">
(единственный тег, добавлен в OnEndBufferContent только для русского сайта)
<link rel="alternate" hreflang="ru" href="https://example.com/page/">
<link rel="alternate" hreflang="en" href="https://example.com/en/page/">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page/">
(полный набор на каждой версии, на en-сайте обратная ссылка)
вторичный источник
157Magento 2: CMS-страницы и главная без группы альтернатив
(у товаров и категорий hreflang есть, у CMS-страниц и главной нет)
(альтернативы заполнены в настройках каждой CMS-страницы)
вторичный источник
158Magento 2: версия с noindex выпадает из набора ссылок
<meta name="robots" content="noindex,follow">
(на одной из локализованных страниц; расширение не выводит ссылки на неё)
(noindex снят с версий кластера либо версия исключена из набора на всех остальных)
вторичный источник
159WPML и Yoast: hreflang выводится для страниц, закрытых noindex в Yoast
<meta name="robots" content="noindex">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(оба на одной странице)
(WPML SEO add-on согласует вывод hreflang с директивами Yoast, по ответу поддержки)
не подтверждено
160Плагин CMS выставляет canonical на чужой URL
<link rel="canonical" href="https://example.com/en/">
(на странице /de-de/, значение подставил плагин)
<link rel="canonical" href="https://example.com/de-de/">
Google напрямую
161Новая CMS по умолчанию добавила hreflang на сайт без международных страниц
<link rel="alternate" hreflang="en" href="https://example.com/">
(на сайте одна версия, тег добавлен шаблоном CMS)
(hreflang убран там, где нет второй версии)
вторичный источник
162Polylang: ждут x-default на внутренних страницах
(на главной x-default есть, на внутренних страницах его нет)
<link rel="alternate" hreflang="x-default" href="https://example.com/en/about/">
(x-default на внутренние страницы добавляют фильтром, если нужна запасная страница)
официальная документация (не Google)
163Polylang: есть только en-GB и en-US, общей en-страницы нет
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/">
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/">
<link rel="alternate" hreflang="en" href="https://example.com/en-us/">
официальная документация (не Google)
164WPML выводит hreflang в начале head, а тема или плагин вставляет выше него iframe или другой тег
<head>
<iframe src="https://example.com/tag-frame.html"></iframe>
<link rel="alternate" hreflang="en" href="https://example.com/en/">
(в настройках WPML положение вывода «Later in the head section»)
(после правки проверить отрисованный head: теги hreflang лежат внутри него)
официальная документация (не Google)
165WPML не проверяет код региона, введённый вручную в поле языка
(в поле hreflang языка в WPML: en-uk)
<link rel="alternate" hreflang="en-uk" href="https://example.com/uk/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/">
Google напрямую
166TranslatePress: в справке пример кода региона «en-UK»
<link rel="alternate" hreflang="en-UK" href="https://example.com/uk/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/">
(код можно подменить фильтром trp_hreflang)
Google напрямую
167Плагин перевода не добавляет x-default по умолчанию (Weglot; в TranslatePress отдельная опция)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(строки x-default в head нет)
<link rel="alternate" hreflang="x-default" href="https://example.com/">
официальная документация (не Google)
168Сайт за reverse proxy: hreflang и переключатель языков указывают на внутренний домен
<link rel="alternate" hreflang="de" href="https://origin.example.com/de/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
официальная документация (не Google)
169Drupal: ждут hreflang на всех страницах от ядра
(на странице-списке без сущности в <head> нет <link rel="alternate" hreflang=...>)
(модуль Hreflang добавляет теги на все страницы)
официальная документация (не Google)
170Drupal 9.4 и новее: ищут hreflang в HTTP-заголовках ответа
(curl -I на странице: заголовка Link с hreflang нет)
<link rel="alternate" hreflang="de" href="https://example.com/de/">
официальная документация (не Google)
171PrestaShop: у бельгийского магазина регион языка nl-NL вместо nl-BE
<link rel="alternate" hreflang="nl-NL" href="https://example.com/nl/">
<link rel="alternate" hreflang="nl-BE" href="https://example.com/nl/">
вторичный источник
172Hugo: x-default по шаблону указывает на первый язык из конфигурации
<link rel="alternate" hreflang="x-default" href="https://example.com/en/">
(селектор языка лежит в корне, а первый язык в config — английский)
<link rel="alternate" hreflang="x-default" href="https://example.com/">
вторичный источник
173Сторонний модуль Magento молча исключает store view без кода языка
(у store view не заполнен код языка: в head нет hreflang для этой версии)
(заполнить код языка store view, например en-GB)
вторичный источник
174WPML SEO 2.2.2 выводил в sitemap коды региона без языка (nz, au)
<xhtml:link rel="alternate" hreflang="nz" href="https://example.com/nz/"/>
<xhtml:link rel="alternate" hreflang="au" href="https://example.com/au/"/>
<xhtml:link rel="alternate" hreflang="en-NZ" href="https://example.com/nz/"/>
<xhtml:link rel="alternate" hreflang="en-AU" href="https://example.com/au/"/>
вторичный источник
З. Концептуальные ошибки · 29
№ОшибкаНеправильноПравильноНадёжность
175Ждут роста позиций от внедрения hreflang
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(расчёт: после добавления тега немецкая страница поднимется в выдаче)
hreflang подменяет адрес уже ранжирующейся страницы на региональный; ранжирующего бонуса нет
официальное заявление сотрудника
176«Одна мелкая ошибка отключает hreflang на всём сайте»
<link rel="alternate" hreflang="en-UK" href="https://example.com/en-gb/">
(одна опечатка в коде; считают, что из-за неё перестаёт работать весь hreflang)
Google отбрасывает только неработающую связь, остальные аннотации страницы продолжают действовать
официальное заявление сотрудника
177Ошибку hreflang считают причиной выпадения страницы из индекса
(в Search Console региональная копия значится «не в индексе»; вывод: hreflang сломан)
hreflang не гарантирует индексацию; близкие по тексту версии собираются в кластер, в отчётах видна canonical, а в выдаче адрес подменяется
официальное заявление сотрудника
178Язык или регион меняют на одном URL по cookie, Accept-Language или IP
https://example.com/ (одна страница отдаёт английский, немецкий или русский текст в зависимости от cookie или IP посетителя)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
<link rel="alternate" hreflang="ru" href="https://example.com/ru/">
Google напрямую
179Автоматический редирект на локальную версию по IP, языку браузера или cookie
GET / отвечает 302 на https://example.com/de-de/ (по IP посетителя)
GET /en/ отвечает 302 на https://example.com/de-de/ (для посетителя из Германии)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
(на каждой версии баннер с предложением сменить страну, без принудительного перехода)
Google напрямую
180Языковые версии массово создают машинным переводом без проверки
<link rel="alternate" hreflang="de" href="https://example.com/de/blog/artikel-1/">
(автоперевод всех страниц на десятки языков без вычитки и без пользы читателю)
переводить и размечать версии, полезные читателю; hreflang только на реально существующие страницы
Google напрямую
181hreflang раскатывают на весь сайт «на всякий случай», хотя неверные версии в выдаче не показываются
<link rel="alternate" hreflang="en" href="https://example.com/en/about/">
(набор на каждой странице сайта, без проверки аналитики)
сначала проверить, попадают ли пользователи на «не ту» версию, и внедрять на страницах, где это происходит (часто главная)
официальное заявление сотрудника
182hreflang считают единственным или определяющим сигналом геотаргетинга
<link rel="alternate" hreflang="en-AU" href="https://example.com/en-au/">
(на странице нет ни локальных адресов, ни телефона, ни валюты, ни ссылок с местных сайтов)
hreflang плюс остальные локальные сигналы: ccTLD, язык, валюта, адреса, телефоны, ссылки
Google напрямую
183Сайты или папки разных стран с одним и тем же английским текстом, без hreflang и canonical
https://example.com/us/ и https://example.com/au/ с одинаковым текстом, без разметки
<link rel="alternate" hreflang="en-US" href="https://example.com/us/">
<link rel="alternate" hreflang="en-AU" href="https://example.com/au/">
<link rel="alternate" hreflang="en" href="https://example.com/us/">
Google напрямую
184Считают, что hreflang гарантирует показ нужной версии
<link rel="alternate" hreflang="de-AT" href="https://example.com/de-at/">
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
(две почти одинаковые немецкие страницы; ожидание: пользователь из Австрии всегда видит /de-at/)
hreflang — подсказка; у почти одинаковых страниц одну выбирают canonical, нужны реальные различия и выбор региона пользователем
официальное заявление сотрудника
185<html lang> считают заменой hreflang или сигналом языка для Google
<html lang="de">
(hreflang нет; ожидание: Google покажет страницу немецким пользователям)
<html lang="de">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
Google напрямую
186Региональные копии на одном языке считают источником штрафа за дубли
(страницы /us/ и /uk/ на одном языке с близким текстом; вывод: «будет штраф»)
штрафа нет: Google собирает дубли в кластер и выбирает canonical, а hreflang подменяет адрес в выдаче
Google напрямую
187Ищут официальный валидатор hreflang Google или отчёт International Targeting
(проверка по отчёту International Targeting в Search Console)
сторонний краулер и проверка в тестовой среде до релиза
Google напрямую
188Разметку выкатывают без теста и не следят за ней после релиза
(hreflang меняется шаблоном, проверки после релиза нет)
тест на staging, краулер до и после релиза, повторные проверки при новых типах страниц и рынках
вторичный источник
189Разметку копируют у конкурента без проверки
(набор hreflang скопирован со страницы конкурента и вставлен в шаблон)
набор собирают из собственных URL и проверяют краулером
вторичный источник
190hreflang для новостных публикаций, где взаимность подтверждается с задержкой
<link rel="alternate" hreflang="en-US" href="https://example.com/us/news/story/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/news/story/">
(статья в US опубликована, версия UK ещё не проиндексирована)
один URL статьи для всех территорий, на разных территориях разные главные страницы
вторичный источник
191При миграции или смене CMS hreflang пропадает на части страниц
(после релиза у части страниц набора hreflang нет, у остальных он есть)
разметка восстановлена на всех страницах набора и проверена краулером
официальное заявление сотрудника
192В материалах цитируют проценты ошибок hreflang без первоисточника («72%», «40%», «90%»)
(текст: «72% сайтов имеют критическую ошибку по Ahrefs 2026», «одна ошибка обнуляет около 40% реализаций по Google»)
Ahrefs, 2023: 67% из 374 756 доменов с hreflang имеют минимум одну проблему из списка; Semrush, 2017: 75% из 20 000 сайтов с минимум одной ошибкой на одной странице; Dan Taylor, 2023: 31,02% сайтов с конфликтами; seotal, 2026: 53,1% из 2 300 главных страниц Юго-Восточной Азии
вторичный источник
193Ждут, что языковые версии делятся сигналами и ссылочным весом через hreflang
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(расчёт: связать версии, чтобы немецкая страница «взяла» авторитет английской)
(каждая версия набирает сигналы сама; hreflang подставляет подходящий URL после выбора страницы)
официальное заявление сотрудника
194Редирект на локальную версию кодом 301 или со всех страниц, а не только с корня кодом 302
HTTP/1.1 301 Moved Permanently
    Location: https://example.com/fr/
(то же с /en/ для посетителей из Франции)
HTTP/1.1 302 Found
    Location: https://example.com/fr/
(редирект только на корне; на /en/ и /fr/ его нет; корень указан в hreflang как x-default)
Google напрямую
195Копируют каждую страницу на десятки страновых версий «ради охвата»
(один английский текст в /us/, /uk/, /au/, /nz/ и ещё десятке папок)
<link rel="alternate" hreflang="en-US" href="https://example.com/us/">
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/">
(версии только там, где различаются язык, рынок или предложение; остальные объединить)
официальное заявление сотрудника
196Приписывают hreflang просадку или рост трафика, не проверив другие причины
(вывод: «после добавления hreflang трафик упал на 70-80%, значит hreflang вредит»)
(до вывода: замер до внедрения, staging с откатом, проверка гео-редиректа, canonical и отчёта по canonical-адресам)
вторичный источник
197Считают зелёный Lighthouse признаком корректного hreflang
<link rel="alternate" hreflang="en-UK" href="https://example.com/en-gb/">
(аудит Lighthouse проходит: язык en допустим, регион не проверяется)
(дополнительно проверить регион, возвратные ссылки и статусы краулером и разметку в sitemap)
Google напрямую
198Проверяют hreflang инструментом, который не видит sitemap или JavaScript, и делают вывод «hreflang нет»
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/"/>
(hreflang лежит только в sitemap; HTML-чекер отвечает: тегов нет)
(проверять все три способа и отрисованный DOM; sitemap читать отдельным инструментом)
официальное заявление сотрудника
199Переносят структуру сайта «как Google, перешедший с доменов стран на единый домен»
(план: слить домены стран в один общий домен «как у Google»)
(структуру выбирать по своим данным: у Google другие обстоятельства)
официальное заявление сотрудника
200Блокируют автоматически переведённые страницы в robots.txt по старой справке
User-agent: *
Disallow: /auto-translated/
(раздел из справки убран; о качестве перевода говорит спам-политика, а не robots.txt)
Google напрямую
201Две страны на одном языке с одинаковым текстом и ценой: ждут, что Google проиндексирует обе
<link rel="alternate" hreflang="de-DE" href="https://example.com/de-de/">
<link rel="alternate" hreflang="de-CH" href="https://example.com/de-ch/">
(тексты, валюта и адрес на обеих версиях совпадают)
<link rel="alternate" hreflang="de" href="https://example.com/de/">
(или различать версии локальными сигналами: валюта, цена, адрес, доставка)
официальное заявление сотрудника
202Миграция доменов стран в подпапки: на старых сайтах hreflang не было, на новом он с четырьмя проблемами, редиректы не покрыли все адреса
(до: es, fr, de, it — отдельные домены без hreflang; после: подпапки на общем домене, hreflang не ведёт на canonical, нет самоссылки, нет обратных ссылок, нет x-default)
(карта 301 «адрес в адрес» плюс hreflang между новыми URL и self-canonical на каждой версии; проверка до запуска)
вторичный источник
203Считают, что кластер не работает, пока Google не увидел все версии сразу
(в кластере en, fr и it уже обойдены, es и de ещё нет)
(выкатывать по мере готовности: Google использует известные версии, остальные подключит после обхода)
официальное заявление сотрудника
И. Другие поисковики и ИИ-ответы · 5
№ОшибкаНеправильноПравильноНадёжность
204Редирект между языковыми или региональными поддоменами по IP, языку или cookie: Яндекс склеивает их в группу сайтов
(https://de.example.com/ редиректит посетителя по IP на https://en.example.com/)
(переключатель языка или региона; обе версии отвечают 200 OK)
официальная документация (не Google)
205Языковые поддомены с одинаковым текстом без регионального задания и альтернативных ссылок (справки Яндекса расходятся: дубли или конкуренция)
(https://en.example.com/ и https://us.example.com/ с одним текстом, без hreflang, регион в Вебмастере не задан)
<link rel="alternate" hreflang="en-US" href="https://us.example.com/">
(в Вебмастере: регион поддомена)
официальная документация (не Google)
206Рассчитывают на hreflang в Baidu и Naver
<link rel="alternate" hreflang="ko" href="https://example.com/ko/">
(расчёт: Naver выберет корейскую версию по hreflang)
<meta http-equiv="content-language" content="ko">
(для Naver по отзывам практиков: отдельный sitemap только с корейской версией; это практика, не официальное правило)
вторичный источник
207Считают, что Bing не поддерживает hreflang
(план: hreflang только для Google и Яндекса; для Bing ничего не делать)
<link rel="alternate" hreflang="en" href="https://example.com/en/">
(hreflang оставить; meta content-language по отзывам практиков остаётся сигналом для Bing)
официальная документация (не Google)
208Ждут, что hreflang управляет языком и страной в ИИ-ответах (AI Overviews, AI Mode, ChatGPT, Perplexity)
<link rel="alternate" hreflang="fr" href="https://example.com/fr/">
(расчёт: французская страница попадёт в ответ ИИ на французский запрос)
(проверять ответы ИИ по странам и языкам отдельно: официального правила нет)
не подтверждено

Порядок проверки своего hreflang

  1. Решите, нужен ли онЕсли в выдаче нет чужой версии и страны не конкурируют друг с другом, можно не внедрять. Это не ошибка, как показали источники выше.
  2. Выберите один способHTML для небольших сайтов и для Яндекса (sitemap он для языковых версий не поддерживает), sitemap для больших каталогов только под Google, заголовок для PDF. Если нужны оба поисковика, базовый способ HTML; sitemap поверх него допустим при совпадающих наборах. Расхождения реальны: у 9 из 26 сайтов с двумя способами наборы различаются.
  3. Проверьте кодыЯзык ISO 639-1, регион ISO 3166-1 Alpha 2, без UK, EU, es-419, подчёркиваний и трёхбуквенных кодов. Регистр приведите к en-GB.
  4. Соберите кластер целикомКаждая страница перечисляет себя и всех остальных, набор одинаков, ссылки взаимные, все адреса абсолютные.
  5. Сверьте canonical, редиректы и noindexКаждая страница кластера отвечает 200, индексируется и ведёт canonical на себя.
  6. Проверьте отрисованный HTMLЧерез «Проверить URL → Просмотреть проверенную страницу» в Search Console: теги hreflang должны быть внутри head.
  7. Следите за результатом в выдачеОткройте поиск с параметрами страны и языка (gl=, hl=) и посмотрите, какая версия показывается.

Эталонный код этой статьи и валидатор на Python (стандартная библиотека, без установки пакетов) лежат в одном архиве. Валидатор проверяет коды по реестру IANA, самоссылку, возвратные ссылки, формат URL, canonical, дубли, синтаксис заголовка и sitemap. В архиве есть сломанная копия эталона с 55 поломками: на ней проверено, что каждая находится. Чего валидатор не делает: не ходит по сети, не проверяет коды ответа, noindex и robots.txt, а нулевой результат означает соответствие описанным правилам, а не гарантию, что Google примет разметку.

Скачать эталон и валидатор (ZIP)

Запуск валидатора
python -X utf8 check_hreflang.py <папка или файл>

Яндекс, Bing и ИИ-поиск

Яндекс

Справка Вебмастера описывает разметку в head, ссылки на все версии на каждой странице и двухбуквенные коды ISO 639-1. Регион — ISO 3166-1 Alpha-2 или ISO 3166-2:RU для регионов России. Список поддерживаемых языков короткий, 40 кодов, и в нём нет китайского, японского, корейского, хинди и тайского. Sitemap для языковых версий Яндекс больше не поддерживает. Дата обновления на странице справки не указана.

Bing

Блог Bing от 19 декабря 2025 года советует использовать hreflang для языкового и регионального таргетинга. Справки Merkle и Conductor (последняя обновлена 23 марта 2026 года) всё ещё утверждают, что Bing разметку не поддерживает, и блог Bing с ними расходится: проверяйте на своём сайте. Как Bing обрабатывает разметку, он не описывает.

ИИ-ответы

Официального заявления о том, как hreflang работает в AI Mode и AI Overviews, я не нашёл: проверены документация, высказывания Мюллера, Bluesky и Reddit. Есть наблюдения отдельных специалистов на малых выборках, но это не правила.

Baidu и Naver

Официальных справок по hreflang я не нашёл. Вторичные источники расходятся (в одних Naver не поддерживает hreflang, в других про sitemap сказано «will still work»), поэтому проверяйте на своём сайте.

Если у вас международный сайт и нужен разбор hreflang, напишите мне. Начну с проверки отрисованного HTML и canonical на выборке страниц по каждому рынку, потом соберу кластеры и сверю с Search Console. Формат работы — на странице «Услуги».

Написать мне

Состав данных и ограничения статьи
  • База источников: документация Google (страницы открыты 19 октября 2026 года, главная страница про hreflang обновлена 21 сентября 2026 года), высказывания сотрудников Google на Reddit, в office hours и подкастах, RFC 5646, реестр IANA, справки Яндекса и Bing, исследования Ahrefs, Semrush, Search Engine Land, seotal и Web Almanac, кейс Clarks от Sistrix, справки инструментов проверки.
  • Reddit напрямую недоступен, поэтому комментарии Мюллера и Иллиса прочитаны в архиве; цитаты даны дословно, даты — по времени комментария. Цитаты Мюллера из видео (2019–2021) взяты из автоматических субтитров.
  • Поведение Google в 2026 году на живых сайтах я не тестировал: эталон основан на документации, а не на эксперименте.
  • Измерения вреда от самих ошибок hreflang для органического трафика нет ни в моей работе, ни в источниках. Утверждения вида «ошибка снижает трафик на X%» в статье не приводятся.
  • Замер на 912 сайтах описывает главные страницы крупных доменов, а не интернет в целом.

Частые вопросы

Если у сайта одна версия контента, нет: Мюллер (Google) говорит, что тогда разметка «doesn’t do anything anyway». Если на одном языке есть отдельные версии для разных стран (например, ru-RU и ru-KZ), да: это один из основных случаев, где она оправдана.

По высказываниям Google, нет: разметка подставляет пользователю нужную версию вместо найденной и ранжирование не меняет. Версии на разных языках не делятся сигналами между собой.

Для Google нет: значение нечувствительно к регистру, принимаются строчные и заглавные коды. По конвенции ISO регион пишут заглавными (en-GB), язык строчными. Среди аннотаций с валидным кодом 23,2% записаны строчными, и это не нарушение.

Google игнорирует пару: «If two pages don’t both point to each other, the tags will be ignored». Остальные пары кластера продолжают работать. В моём замере хотя бы у одной проверенной альтернативы ссылки назад нет у 82 из 814 сайтов (10,1%); из sitemap возврат я не проверял, поэтому это верхняя оценка.

Это рекомендация, а не требование. x-default задаёт запасную страницу для пользователей, чей язык не совпал ни с одной версией; лучше всего он работает на странице выбора языка. В замере x-default нет у 28,7% сайтов с hreflang.

Для Google три способа равнозначны. HTML-теги подходят небольшим сайтам и нужны для Яндекса, sitemap удобнее для больших каталогов только под Google, заголовок Link нужен для PDF. Если нужны оба поисковика, базовый способ HTML. Конфликт возникает, если один код ведёт на разные URL; в моей подвыборке наборы различаются у 9 из 26 сайтов с двумя способами.

Справка Вебмастера описывает разметку в head и двухбуквенные коды ISO 639-1. Список поддерживаемых языков короткий (40 кодов), sitemap для языковых версий Яндекс больше не поддерживает. Даты обновления на странице справки нет.

Источники

Страницы открыты 19 октября 2026 года. Где у страницы есть дата обновления, она указана. Комментарии Джона Мюллера и Гэри Иллиса на Reddit прочитаны в архиве, ссылок на них нет.

Google

Стандарты

Яндекс и Bing

Исследования