hreflang
атрибут, що пов'язує сторінку з її перекладами
Що це таке
Атрибут hreflang на посиланні повідомляє, якою мовою написано сторінку на
іншому його кінці. HTML дозволяє ставити його на елементи a, area і link,
але відомим його зробило одне застосування: набір елементів
link rel="alternate" у head сторінки, по одному на кожну мовну версію, яким
сайт повідомляє пошуковим системам, що кілька адрес містять той самий вміст
різними мовами.
<link rel="alternate" hreflang="en" href="https://example.com/guide/" />
<link rel="alternate" hreflang="da" href="https://example.com/da/guide/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/guide/" />
Стандарт HTML називає цей атрибут «суто рекомендаційним». Його значення мусить
бути коректним мовним тегом за BCP 47, а браузер має визначати мову завантаженої
сторінки з самої сторінки, а не з посилання, яке до неї привело. У поєднанні з
rel="alternate" атрибут hreflang, що відрізняється від мови самого
документа, позначає ціль як переклад.
Пошукові системи перетворили цю рекомендаційну примітку на протокол. Google
описує три рівноцінні способи передати набір: елементи link у head,
заголовок HTTP Link для PDF та інших файлів без head і записи в XML-карті
сайту. Кожна версія перелічує саму себе й усі інші версії, з повними абсолютними
адресами. Пара враховується лише тоді, коли обидві сторінки називають одна одну,
тож чужий сайт не може оголосити себе перекладом ваших сторінок. Коди
складаються з мови за ISO 639-1 і, за потреби, регіону за ISO 3166-1, а сам
регіон без мови недійсний. Зарезервоване значення x-default вказує сторінку
для читачів, чия мова не збігається з жодною з інших, і, як зазначає Google,
задумане воно для сторінок вибору мови.
Із ним легко сплутати двох сусідів. Атрибут lang каже, якою мовою текст перед
читачем; hreflang каже, якою мовою сторінка, на яку веде посилання. Google
зазначає, що не використовує жодного з них, щоб визначити мову сторінки, тож
hreflang не зробить сторінку данською; він повідомляє пошуковій системі, що
данська сторінка, яку та вже розпізнала, належить до однієї групи з англійською.
А канонічна URL зливає дублікати в одну проіндексовану адресу, тоді як
hreflang лишає в індексі кожну версію й каже, яку з них кому показувати.
Чому це важливо
hreflang фіксує одне рішення: чи утворюють мовні версії сторінки одну групу,
чи їх оцінюють як окремі сторінки. Окремо кожна версія змагається сама за себе,
і пошукова система може показати данському читачеві англійську сторінку або
вивести обидві версії в тих самих результатах. Оголошені групою, версії
сприймаються як один вміст, і пошукова система може запропонувати ту, що
відповідає мовним налаштуванням читача.
Група має сенс лише тоді, коли версії справді містять той самий вміст. Сайтові
однією мовою hreflang не потрібен узагалі, а два мовні розділи, що різняться
по суті, теж не група. Регіональні варіанти з невеликими відмінностями, як-от
сторінки en-GB і en-US з різними цінами, утворюють групу так само.
Ціна — облік, і він зростає з квадратом кількості мов. Кожна версія кожної
сторінки несе повний список, тож коли один переклад додають, переносять чи
знімають, змінюється head усіх сторінок-сестер, а список, правильний на
більшості сторінок і хибний на кількох, ламається тихо: пари, що ведуть в обидва
боки, використовуються, решта відкидається, і жодної видимої помилки немає. Тому
hreflang погано пасує ручному редагуванню й природно — генераторові, який
виводить набір кожної сторінки з одного списку. Від hreflang залежить, яку з
кількох версій побачить користувач пошуку.
Як це виглядає на практиці
Цей сайт публікує кожну сторінку трьома мовами з одного дерева вмісту, тож кожна сторінка має сталий набір сестер, які треба оголосити.
Один шаблон вирішує, які переклади оголошувати, і п’ять місць читають його
рішення: набір hreflang у head, теги og:locale:alternate, якими
користуються попередні перегляди посилань, альтернативи в карті сайту,
inLanguage у структурованих даних сайту і, після ще одного віднімання, мовна
смуга, яку бачить читач. Список містить і саму сторінку, а отже дає те посилання
на себе, якого вимагають правила. Коди називають лише мови, en, da і uk,
тож кожну версію пропонують усім читачам цієї мови, де б вони не були, а
англійський запис пишеться вдруге як x-default. І head, і карта сайту несуть
набір, згенерований з того самого списку, тож розійтися вони не можуть.
Поділ між машинами й читачами навмисний.
Українська версія проіндексована й указана в картах сайту, а перемикач у верхній панелі її не пропонує,
і в мовній конфігурації це один прапорець: пошуковому роботові й далі
повідомляють про українську в обидва боки, змінюється лише меню для читача.
Другий прапорець, для мови, яку вже збирають, але яка ще не готова, прибирає її
з обох списків і позначає її сторінки noindex. Сторінка такою мовою теж не
оголошує сестер, бо hreflang від неоголошеної сторінки до оголошеної — це
пара, яку пошукова система бачить лише з одного кінця.
Копії підкоряються тій самій логіці. Сторінка на одному з тематичних субдоменів,
чия канонічна URL вказує на основний сайт, узагалі не виводить hreflang: набір
читають на тій сторінці, яку пошукова система прийняла як канонічну, а копія, що
називала б переклади свого хоста, суперечила б власній канонічній URL. Перемикач
мов на ній усе одно працює, бо читач, якому потрібна данська, однаково має її
отримати.
Перевірка зібраних сторінок вимагає, щоб кожна сторінка з альтернативами містила
x-default і власну мову, а кожна альтернатива була зібраною сторінкою
оголошеною мовою й вела назад. Правило про посилання на себе потрібне не для
галочки. Генератор має два списки з майже однаковими назвами: .Translations,
що не містить поточної сторінки, і .AllTranslations, що містить, і помилка в
одне слово прибирає власну мову кожної сторінки і з head, і з мовної смуги
водночас, тож вони й далі узгоджені між собою. На навмисно зламаній збірці ця
одна вимога виявилася єдиною в перевірці, що зловила 528 із 792 сторінок.
Де виникають проблеми
Користувачам пошуку показують версію не тією мовою. Данського читача ведуть на англійську сторінку, або обидві версії стоять поруч. Пари ведуть в один бік: данська сторінка називає англійську, але англійська досі перелічує лише ті мови, що були раніше, а пошукові системи ігнорують пару без зворотного посилання. Будуйте набір кожної сторінки з одного списку, що містить і саму сторінку, і перевіряйте взаємність на зібраних сторінках.
Анотації цілої мови нічого не дають. Розмітка на місці й є коректним HTML,
але версії трактують як не пов’язані між собою. Коди означають щось інше, ніж
задумано: ua чи dk там, де мови мають коди uk і da, be в значенні
Бельгії, хоча це код білоруської мови, або en-UK замість en-GB, бо UK —
зарезервований код регіону, який Google ігнорує. Беріть мову з ISO 639-1,
додавайте регіон з ISO 3166-1 лише там, де вміст справді різниться між країнами,
і пам’ятайте, що коректний тег BCP 47 Google може й не підтримувати.
Переклади випадають з індексу. У пошуку з’являється лише мова оригіналу, а
переклади трактують як його дублікати. Кожен переклад називає своєю канонічною
URL оригінал, а це просить злити переклад з оригіналом, тоді як його hreflang
просить його показувати. Робіть кожну мовну версію власною канонічною URL;
Google радить, щоб канонічна сторінка була тією самою мовою.
Сторінку, що просила лишитися поза пошуком, однаково оголошують. Чорнеткова
мова з позначкою noindex з’являється серед альтернатив опублікованих сторінок
або сама перелічує їх у своєму head. Оголошення й директиву задано в різних
місцях, тож сайт дає пошуковому роботові дві відповіді про ту саму адресу.
Вирішуйте для кожної мови окремо, оголошена вона в обидва боки чи в жоден,
тримайте це рішення в одному параметрі, який читають усі списки, і звіряйте з
ним зібрані сторінки.
Що почитати далі
- HTML Standard: the hreflang attribute — що атрибут означає на посиланні і чому браузер не має йому довіряти.
- HTML Standard: link type “alternate”
— як
hreflangіtypeописують переклад або інший формат того самого документа. - RFC 5646: Tags for Identifying Languages — синтаксис BCP 47, якому має відповідати значення атрибута.
- Google Search Central: localized versions of your pages
— три способи передати набір, правило взаємності та
x-default.