22. Интернационализация (i18n)
Astro предоставляет встроенную поддержку маршрутизации для многоязычных сайтов начиная с версии 3.5. Вместо того чтобы изобретать велосипед или тянуть сторонние библиотеки, вы получаете нативное решение прямо из коробки.
Настройка i18n в astro.config.mjs
Заголовок раздела «Настройка i18n в astro.config.mjs»Всё начинается с конфигурации. Определяем локали и язык по умолчанию:
import { defineConfig } from 'astro/config';
export default defineConfig({ i18n: { defaultLocale: 'ru', locales: ['ru', 'en', 'ja'], routing: { prefixDefaultLocale: false, // /about вместо /ru/about }, fallback: { ja: 'en', // японский → английский, если нет перевода }, },});Параметр prefixDefaultLocale: false означает, что страницы на языке по умолчанию будут доступны без префикса: /about, а не /ru/about. Остальные языки получат префикс: /en/about, /ja/about.
Структура URL
Заголовок раздела «Структура URL»После настройки Astro автоматически обрабатывает маршрутизацию:
/ → Главная (русский, по умолчанию)/en/ → Home (английский)/ja/ → ホーム (японский)/about → О нас (русский)/en/about → About (английский)/ja/about → 私たちについて (японский)Структура файлов в src/pages должна отражать эту схему:
src/pages/├── index.astro ← /├── about.astro ← /about├── en/│ ├── index.astro ← /en/│ └── about.astro ← /en/about└── ja/ ├── index.astro ← /ja/ └── about.astro ← /ja/aboutХелпер getRelativeLocaleUrl()
Заголовок раздела «Хелпер getRelativeLocaleUrl()»Для генерации корректных ссылок используйте встроенный хелпер. Он сам добавляет нужный префикс в зависимости от локали:
---import { getRelativeLocaleUrl } from 'astro:i18n';
const locale = Astro.currentLocale ?? 'ru';const aboutUrl = getRelativeLocaleUrl(locale, 'about');const blogUrl = getRelativeLocaleUrl(locale, 'blog');---
<nav> <a href={getRelativeLocaleUrl(locale, '/')}>Главная</a> <a href={aboutUrl}>О нас</a> <a href={blogUrl}>Блог</a></nav>Если locale = 'en', то getRelativeLocaleUrl('en', 'about') вернёт /en/about. Если locale = 'ru' (default), вернёт /about.
Переводы через Content Collections
Заголовок раздела «Переводы через Content Collections»Лучший подход для перевода контента — использовать коллекции с мультиязычной структурой:
src/content/└── docs/ ├── ru/ │ ├── getting-started.md │ └── installation.md ├── en/ │ ├── getting-started.md │ └── installation.md └── ja/ └── getting-started.mdЗапрос нужной локали:
import { getCollection } from 'astro:content';
// Получаем все статьи для текущей локалиconst locale = Astro.currentLocale ?? 'ru';const docs = await getCollection('docs', ({ id }) => { return id.startsWith(locale + '/');});Определение локали пользователя
Заголовок раздела «Определение локали пользователя»Astro предоставляет Astro.currentLocale и Astro.preferredLocale для работы с локалями:
---const currentLocale = Astro.currentLocale; // 'ru', 'en' или 'ja'const preferred = Astro.preferredLocale; // из Accept-Language заголовкаconst allLocales = Astro.preferredLocaleList; // ['en-US', 'ru', 'ja']---Поддержка RTL (right-to-left)
Заголовок раздела «Поддержка RTL (right-to-left)»Для языков с письмом справа налево (арабский, иврит) достаточно задать направление в HTML:
---const isRTL = ['ar', 'he', 'fa'].includes(Astro.currentLocale ?? '');---<html lang={Astro.currentLocale} dir={isRTL ? 'rtl' : 'ltr'}>