Skip to content
Apothem

Интернационализация (i18n)

Как сайт документации Apothem объявляет свою группу локалей, выдаёт ссылки hreflang на альтернативные языки и рендерит текст справа налево — на двенадцати языках.

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

Сводка решений

  • Платформа: Next.js App Router + Fumadocs. Сайт собирается из site/. Группа локалей объявлена в site/lib/i18n.ts, а механизм ссылок на альтернативные языки находится в site/lib/hreflang.ts.
  • Группа локалей: двенадцать языков. Группа Modern Dev из двенадцати локалей является каноническим источником истины, с английским в качестве исходной локали; каждая из одиннадцати целевых локалей первично заполнена машинным переводом из набора английских страниц; проверка человеком по каждой локали ведётся, а fallbackLanguage: 'en' покрывает любую страницу, которую локаль ещё не создала.
  • Маршрутизация по локалям: включена для всей группы. Каждая локаль подключена к маршрутизации и доступна по собственному префиксу URL (/es/, /zh-cn/, …); английский обслуживается в корне сайта.
  • Механизм hreflang: активен. Каждая страница выдаёт набор <link rel="alternate">, покрывающий каждую локаль, плюс резервный вариант x-default, так что поисковые системы видят полный кластер альтернативных языков. Ссылки определяются для каждого файла по файловой системе, поэтому страница объявляется в локали только тогда, когда она в этой локали есть.
  • Рендеринг справа налево: активен. Общие таблицы стилей повсюду используют логические свойства CSS, поэтому арабские страницы рендерятся корректно под dir="rtl".
  • Проверка перевода: отслеживается по страницам. Страницы локалей, заполненные машинным переводом, публикуются и несут во фронтматтере machineTranslated: true, пока их не проверит человек; этот флаг — метаданные для отслеживания проверки, и страница его не отображает. Для любой страницы, которой нет в локали, резервным языком служит английский. Проверка 80% страниц локали — это цель проверки, а не условие публикации.
  • Актуальность перевода: отслеживается по страницам. Каждая страница локали записывает английский текст, с которого она была переведена. Когда английская страница позже меняется, переведённая страница показывает однострочное примечание со ссылкой на английскую страницу, которая остаётся авторитетной.

Группа локалей

Группа Modern Dev объявляет двенадцать локалей. Английский обслуживается в корне сайта; каждая из одиннадцати целевых локалей первично заполнена машинным переводом из набора английских страниц и доступна по собственному префиксу URL, а fallbackLanguage: 'en' покрывает любую ещё не созданную страницу.

КодПутьЯзыкНаправление
en/АнглийскийLTR
zh-CN/zh-cn/Упрощённый китайскийLTR
es/es/ИспанскийLTR
pt-BR/pt-br/Бразильский португальскийLTR
fr/fr/ФранцузскийLTR
de/de/НемецкийLTR
ja/ja/ЯпонскийLTR
ko/ko/КорейскийLTR
ru/ru/РусскийLTR
id/id/ИндонезийскийLTR
ar/ar/АрабскийRTL
hi/hi/ХиндиLTR

Группа является единственным источником истины; поправки к ней проходят через осознанное решение, никогда не через молчаливое редактирование.

Как работает hreflang

site/lib/hreflang.ts строит карту alternates.languages, которую Next.js рендерит в <head> каждой страницы. Её построение соблюдает одно правило: ссылка на альтернативный язык для локали выдаётся только тогда, когда в этой локали создана данная страница, что определяется для каждого файла по файловой системе (site/lib/translated-pages.ts). Поэтому полностью переведённая страница выдаёт полный кластер:

<link rel="alternate" hreflang="en" href="https://apothem.ahmedgad.com/..." />
<link rel="alternate" hreflang="es" href="https://apothem.ahmedgad.com/es/..." />
<link rel="alternate" hreflang="ar" href="https://apothem.ahmedgad.com/ar/..." dir="rtl" />
<!-- … one per cohort locale … -->
<link rel="alternate" hreflang="x-default" href="https://apothem.ahmedgad.com/..." />

Ссылка canonical страницы — всегда её собственный URL; она никогда не указывает на другую локаль.

Рендеринг справа налево

Арабский — локаль группы с письмом справа налево, и сайт рендерит его корректно:

  • Только логические свойства CSS. Общие таблицы стилей и компоненты используют логические свойства (margin-inline-start, padding-inline-end, text-align: start, inset-inline-start), а не физические (margin-left, text-align: left). Логические свойства автоматически отражаются под dir="rtl", поэтому одна и та же таблица стилей корректно обслуживает оба направления.
  • Атрибут направления. Арабские страницы устанавливают dir="rtl" на элементе <html> вместе с lang="ar".
  • Двунаправленный контент. Строки со смешанным направлением — например, английская команда внутри арабского абзаца — оборачиваются в <bdi>, чтобы встроенный фрагмент слева направо корректно рендерился внутри потока справа налево.

Добавление или обновление локали

Группой и маршрутизацией управляет site/lib/i18n.ts:

  1. Создайте страницу под content/docs/<locale>/, повторяющую английский источник.
  2. Зафиксируйте английский текст, который она переводит: из site/ выполните node scripts/translation-sources.mjs --stamp <locale>/<path>.mdx, который записывает хеш английской страницы в поле frontmatter sourceHash страницы локали.
  3. Убедитесь, что локаль указана в ROUTED_LOCALES (сегодня маршрутизируются все двенадцать локалей группы).
  4. Её ссылка hreflang и маршруты определяются автоматически по файловой системе.

Устаревшие переводы

sourceHash страницы локали — это хеш английской страницы, с которой она была переведена; он охватывает английский frontmatter и прозу, но не генерируемые таблицы, которые генератор справочника переписывает сразу во всех языках. Во время сборки сайт вычисляет хеш текущей английской страницы; когда два хеша различаются, переведённая страница показывает примечание о том, что английская страница изменилась с момента перевода, со ссылкой на неё. Выполните node scripts/translation-sources.mjs из site/, чтобы вывести список устаревших страниц по каждой локали, затем обновите каждый перевод и проставьте для него отметку, как в шаге 2 выше. Страница, которую локаль вообще не перевела, отдаётся из английского источника с пометкой, что это английский текст.

Английский остаётся источником истины; каждая страница локали дословно повторяет структуру, ссылки и примеры кода своего английского аналога.

On this page