Согласовывайте язык только для /, а явные URL, такие как /en/ и /fr/, всегда должны отдавать указанную в них языковую версию. В этом руководстве издателю, работающему на Mac, показано, как задать такое поведение, сохранить доступность ссылок на документы и проверить результат.
В качестве рабочего примера используется условная общедоступная коллекция документов с английской и французской версиями краткого руководства по расположению фигур. Корневая страница служит для выбора языка, а её вступительный текст может адаптироваться к запросу. Все примеры адресов описывают предполагаемую структуру; они не означают, что по этим адресам сейчас размещены страницы.
Определите поведение URL до изменения языковых настроек
Начните с краткого описания правил маршрутизации. В этом примере корневая страница помогает читателям выбрать язык, а два явных пути содержат полный перевод документа. Google рекомендует использовать отдельные URL для языковых версий и не перенаправлять читателей между ними автоматически на основании предполагаемого языка. Видимые ссылки позволяют читателям сделать собственный выбор. Управление многоязычными и мультирегиональными сайтами.
| Запрошенный путь | Предполагаемый ответ | Влияние языковых предпочтений |
|---|---|---|
/ |
Выбор языка с кратким вступлением | Может меняться вступление и предлагаемая ссылка |
/en/ |
Полный документ на английском | Язык документа не меняется |
/fr/ |
Полный документ на французском | Язык документа не меняется |
| Неопубликованный путь | Ответ об отсутствии страницы | Нельзя незаметно подменять его другим документом |
Используйте эту таблицу как техническое задание. Выбирайте язык только после проверки, что запрос направлен к корневой странице. Общее правило, которое выполняется до обработки каждого запроса страницы, может переопределить явный выбор и нарушить заданный контракт.
Например, пользователь, перешедший по /fr/, должен получить французский документ, даже если в его запросе указан предпочтительный английский язык. Предпочтение английского полезно в начальной точке, когда выбор ещё не сделан; явный путь в других случаях уже задаёт этот выбор. На этом принципе приоритета основаны рекомендации в статье.
Оставляйте обе языковые ссылки видимыми на каждой странице. На корневой странице предложенный язык может упростить первый выбор, не скрывая другой вариант. На страницах полных документов переключатель должен вести прямо к соответствующему документу.
Выберите предсказуемую политику выбора языка корневой страницы
Заголовок Accept-Language содержит предпочтительные языки ответа с весовыми коэффициентами, например fr;q=0.9,en;q=0.5. Он не обязывает сервер предоставлять все запрошенные языки. Нулевой вес означает, что язык неприемлем. Заголовок Content-Language описывает предполагаемую аудиторию возвращаемого представления, но не выбирает маршрут. RFC 9110: Семантика HTTP, разделы 8.5, 12.4.2 и 12.5.4.
До настройки чего-либо запишите список поддерживаемых языков и резервный вариант. В этом примере используются вступления на английском и французском. Если в запросе нет подходящего языка, показывается английское вступление и оба варианта языка. Это пример издательского решения, а не требование HTTP.
Используйте механизм сопоставления языков с явно заданной политикой. В RFC 4647 различаются фильтрация и поиск по языку: поиск выбирает один результат, обрабатывает запрошенные диапазоны в порядке приоритета и постепенно удаляет подметки, чтобы найти соответствие. Также приложения, использующие поиск, должны определить поведение по умолчанию. Поэтому запрос fr-CA при поиске может привести к вступлению на поддерживаемом обобщённом языке fr. RFC 4647: Сопоставление языковых меток, разделы 3.4–3.4.1.
Не выбирайте язык, просто находя в заголовке первое вхождение fr или en. Такой упрощённый подход не учитывает веса и исключения. Механизм сопоставления должен разбирать предпочтения, учитывать исключения с нулевым весом и затем применять задокументированный резервный вариант.
| Предпочтение в запросе корневой страницы | Ожидаемый результат в этом примере |
|---|---|
| Заголовок отсутствует | Английское вступление и оба варианта |
fr |
Французское вступление и оба варианта |
fr-CA,fr;q=0.9,en;q=0.5 |
Французское вступление |
en;q=0.9,fr;q=0.2 |
Английское вступление |
de |
Резервная страница выбора |
fr;q=0,en;q=1 |
Английское вступление; французский не выбирается |
*;q=0 |
Явно определённая обработка неподдерживаемого языка |
Для последней строки нужно принять осознанное решение. В рамках этой схемы выбора укажите, что при запросе, исключающем все языки, показывается резервная страница выбора, поскольку приложение не выполняет это предпочтение, а не потому, что запросу соответствует английский. Если требуется строгое согласование, определите и проверьте соответствующее поведение для неприемлемого ответа. В любом случае не допускайте, чтобы ноль случайно трактовался как обычное низкое предпочтение.
Согласуйте язык документа, ссылки и поисковые аннотации
Для каждого HTML-документа задайте атрибут lang в соответствии с его основным языком: en для английской страницы и fr для французской. В WHATWG lang определён как основной язык содержимого элемента и текстовых атрибутов; если он не задан, язык наследуется от родительского элемента. Один лишь языковой префикс этого не обеспечивает. Стандарт HTML: атрибуты lang и xml:lang.
Проверьте навигационные ссылки наряду с текстом страницы. Относительные URL разрешаются относительно базового URL согласно стандарту WHATWG URL. Например, если у документа нет другого базового URL, fr/ относительно https://example.com/en/ разрешается в https://example.com/en/fr/; /fr/ ведёт к французскому пути на этом же источнике. Для видимого переключателя используйте предполагаемый абсолютный путь. Стандарт URL: запись и разбор URL.
Поисковые аннотации выполняют отдельную задачу. Google поддерживает аннотации эквивалентных языковых версий через HTML, заголовки HTTP или карту сайта. Выберите один удобный способ. Для каждой версии укажите её саму и соответствующие версии, используя полные URL; версии должны ссылаться друг на друга через эти аннотации. Целевой страницей x-default может быть корневая страница выбора. Как сообщить Google о локализованных версиях страницы.
Для условной коллекции соответствия аннотаций таковы:
| Аннотация | Условный адрес |
|---|---|
en |
https://example.com/en/ |
fr |
https://example.com/fr/ |
x-default |
https://example.com/ |
Добавьте эти связи с помощью поддерживаемого издательской системой механизма аннотаций. Это описание структуры, а не исполняемая разметка. x-default не настраивает согласование на сервере и не предоставляет перевод. Google также указывает, что определяет язык страницы алгоритмически, а не использует hreflang или HTML lang для его распознавания. Как сообщить Google о локализованных версиях страницы.
Полные переводы должны быть доступны независимо от адаптации корневой страницы. Google сообщает, что его поисковый робот отправляет запросы без Accept-Language, и предупреждает: адаптивные к локали страницы могут остаться не обнаруженными. Надёжный резервный вариант и прямые URL языковых версий решают эту проблему доступности, не требуя от поискового робота запрашивать разные варианты вступления на корневой странице. Как Google сканирует страницы, адаптивные к локали.
Настройте кэширование корневых ответов с учётом выбора языка
Если выбор языка на корневой странице зависит от Accept-Language, добавьте Vary: Accept-Language к ответам этой страницы, включая резервный вариант. Сохраните все существующие поля вариации. В приведённом ниже примере французского ответа корневой страницы показана часть заголовка, а не полное HTTP-сообщение: RFC 9110: Семантика HTTP, раздел 12.5.5.
Content-Type: text/html; charset=utf-8
Content-Language: fr
Vary: Accept-Language
RFC 9111 требует от кэша сверять поля запроса, указанные в Vary, прежде чем повторно использовать сохранённый ответ без повторной проверки. Это важно, поскольку URL корневой страницы остаётся прежним, а её вступление меняется. Vary описывает входные данные для выбора, но не реализует механизм сопоставления языков. RFC 9111: Кэширование HTTP, раздел 4.1.
В рамках этой схемы документы /en/ и /fr/ не зависят от Accept-Language. Проверьте весь путь доставки, включая любой общий кэш, на соответствие правилам маршрутизации. В качестве практической диагностики поочерёдно отправьте запросы к корневой странице с предпочтением английского и французского, а затем поменяйте их порядок. Если корневая страница снова и снова возвращает язык из предыдущего запроса, проверьте совместно поведение кэша и маршрутизацию.
Проверьте правила с Mac
Сначала подготовьте три условные страницы на общедоступном демонстрационном источнике. Приведённая ниже проверка предполагает, что на этом источнике находятся только страницы демонстрационной коллекции по адресам /, /en/ и /fr/. Она не создаёт страницы и не настраивает хост. Указанные выше условные адреса example.com не являются работающей тестовой установкой.
Откройте приложение Mac Terminal и выполните curl --version, чтобы убедиться, что curl доступен. Затем вставьте следующий полный диагностический скрипт оболочки. По запросу введите адрес демонстрационного источника вместе с https://, без пути и завершающей косой черты.
printf 'Public demo origin, without a trailing slash: '
IFS= read -r demo_origin
case "$demo_origin" in
https://*) ;;
*) printf 'Enter an HTTPS origin.\n' >&2; exit 1 ;;
esac
for demo_path in / /en/ /fr/; do
for demo_language in '' 'en' 'fr' 'fr-CA,fr;q=0.9,en;q=0.5' 'en;q=0.9,fr;q=0.2' 'de' 'fr;q=0,en;q=1'; do
printf '\nPath: %s | Accept-Language: %s\n' \
"$demo_path" "${demo_language:-absent}"
curl --silent --show-error --connect-timeout 5 --max-time 15 \
--dump-header - --header "Accept-Language: $demo_language" \
"$demo_origin$demo_path" || exit 1
done
done
Диагностика выводит заголовки ответов и тела сообщений. Параметр curl --header задаёт предпочтение; пустое значение удаляет этот заголовок. --dump-header - выводит заголовки в стандартный поток вывода, а ограничения по времени ограничивают длительность каждой передачи. Перенаправления намеренно не отслеживаются, чтобы неожиданный редирект оставался заметным. curl — руководство по использованию.
Синтаксис скрипта оболочки проверен; здесь не утверждается, что демонстрационная версия развёрнута или что работа маршрутизации языков проверена в реальном времени. При ошибке передачи curl скрипт останавливается, однако HTTP-ответ с ошибкой всё равно может появиться в выводе — его нужно проверить.
Сравните ответы корневой страницы с таблицей предпочтений. Затем проверьте, что каждый ответ /en/ содержит английский текст, а каждый ответ /fr/ — французский, независимо от указанного предпочтения. Проверьте коды состояния, неожиданные поля Location, указанное возвращённое значение языка и фактический текст документа. Если заголовок верен, а тело нет, проверка всё равно не пройдена.
Наконец, откройте оба явных URL в браузере. Перейдите по переключателю языка, перезагрузите целевую страницу и проверьте адресную строку. Так можно обнаружить ошибки навигации, которые не выявляет успешный прямой запрос. Отдельно проверьте неопубликованный путь и убедитесь, что на нём незаметно не отображается один из полных документов.
Используйте стабильную страницу выбора, если согласование недоступно
Для этой схемы требуется уровень обслуживания, способный читать заголовок запроса и выбирать ответ. Механизмы языка документа и URL в WHATWG описывают документы и адреса; добавление атрибута lang или изменение текста ссылки само по себе не создаёт согласование HTTP. Выбор в зависимости от запроса должен быть настроен на уровне доставки HTTP. Стандарт HTML, RFC 9110: Семантика HTTP.
Если издательская система не предоставляет такой возможности обслуживания, используйте фиксированную корневую страницу выбора с прямыми ссылками на полные языковые версии. Это сохраняет за читателем право выбора и соответствует рекомендации Google использовать отдельные URL языковых версий и видимые ссылки переключения. Здесь не предполагается использование функции согласования какого-либо конкретного издательского продукта. Управление многоязычными и мультирегиональными сайтами.
Практический критерий приёмки прост: предпочтения могут помочь на корневой странице, а явные ссылки на языковые версии должны оставаться надёжными адресами. В завершение задокументируйте резервный вариант, укажите соответствующие языки документов и взаимные аннотации языковых версий, а также соберите свидетельства по отдельным запросам, подтверждающие соблюдение правил маршрутизации.
Источники
- RFC 9110: Семантика HTTP — IETF / RFC Editor.
- RFC 9111: Кэширование HTTP — IETF / RFC Editor.
- RFC 4647: Сопоставление языковых меток — IETF / RFC Editor.
- Стандарт HTML — WHATWG.
- Стандарт URL — WHATWG.
- Управление многоязычными и мультирегиональными сайтами — Google Search Central.
- Как сообщить Google о локализованных версиях страницы — Google Search Central.
- Как Google сканирует страницы, адаптивные к локали — Google Search Central.
- curl — руководство по использованию — curl.