Перейти к содержимому

Маршрутизация и интернационализация (i18n)

Функции интернационализации (i18n) Astro позволяют адаптировать ваш проект для международной аудитории. Этот API маршрутизации помогает создавать, использовать и проверять URL-адреса, которые генерирует ваш многоязычный сайт.

Маршрутизация i18n в Astro позволяет реализовать поддержку нескольких языков с возможностью настройки языка по умолчанию, вычисления относительных URL-адресов страниц и учёта предпочитаемых языков из настроек браузера пользователя. Вы также можете указать резервные языки для каждой локали отдельно, чтобы посетители всегда попадали на существующий контент.

Astro использует мидлвар для реализации логики маршрутизации. Эта функция мидлвара занимает первую позицию, где она ожидает каждый Response, поступающий от любых дополнительных мидлваров и каждого маршрута страницы, прежде чем выполнить собственную логику.

Это означает, что сначала выполняются операции (например, перенаправления) из ваших собственных мидлваров и логики страниц, затем рендерятся маршруты, и только после этого мидлвар i18n выполняет свои действия, например, проверку соответствия локализованного URL-адреса допустимому маршруту.

Вы также можете добавить свою логику i18n в дополнение или вместо мидлвара Astro i18n, что даст вам ещё больше контроля над маршрутами при сохранении доступа к вспомогательным функциям astro:i18n.

В объекте конфигурации i18n необходимо указать список всех поддерживаемых языков (locales) и язык по умолчанию (defaultLocale), который должен быть одним из языков в списке locales. Кроме того, вы можете настроить специфическое поведение маршрутизации и резервных локалей.

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "pt-br"],
defaultLocale: "ru",
}
})

Организуйте папки с контентом, разделяя его по языкам. Создайте отдельные папки /[locale]/ в любом месте внутри src/pages/, и маршрутизация на основе файлов Astro создаст страницы по соответствующим URL-путям.

Имена папок должны точно соответствовать элементам в списке locales. Включайте локализованную папку для defaultLocale только в том случае, если вы настроили prefixDefaultLocale: true, чтобы отображать языковой префикс в URL для языка по умолчанию (например, /ru/about/).

  • Директорияsrc
    • Директорияpages
      • about.astro
      • index.astro
      • Директорияen
        • about.astro
        • index.astro
      • Директорияpt-br
        • about.astro
        • index.astro

После настройки i18n-маршрутизации вы сможете вычислять ссылки на страницы сайта, используя вспомогательные функции, такие как getRelativeLocaleUrl(), доступные в модуле astro:i18n. Эти функции всегда возвращают правильный локализованный путь.

Вы также можете прописывать ссылки вручную.

src/pages/ru/index.astro
---
import { getRelativeLocaleUrl } from 'astro:i18n';
// defaultLocale = "ru"
const aboutURL = getRelativeLocaleUrl("ru", "about");
---
<a href="/get-started/">Начнём!</a>
<a href={getRelativeLocaleUrl('ru', 'blog')}>Блог</a>
<a href={aboutURL}>О нас</a>

Встроенная файловая маршрутизация Astro автоматически создает URL-маршруты на основе структуры файлов в src/pages/.

При настройке i18n-маршрутизации информация об этой структуре доступна функциям i18n, чтобы они могли генерировать и проверять маршруты в вашем проекте. Многие из этих опций можно комбинировать для гибкой настройки каждого языка.

Вы также можете реализовать собственную логику маршрутизации вручную для максимального контроля.

Добавлено в: astro@3.5.0

Этот параметр определяет, должны ли URL-адреса для языка по умолчанию использовать языковой префикс (например, /ru/about/).

Все остальные поддерживаемые языки всегда используют локализованный префикс (например, /en/ или /english/), а файлы контента должны находиться в соответствующих папках. Данная опция позволяет указать, должен ли язык по умолчанию следовать той же структуре.

Этот параметр также определяет местоположение файлов для языка по умолчанию (например, src/pages/about/ или src/pages/ru/about), так как структура файлов и URL должны совпадать для всех языков.

  • "prefixDefaultLocale: false" (по умолчанию): URL для языка по умолчанию не имеют префикса /[locale]/. Все остальные локали имеют его.

  • "prefixDefaultLocale: true": Все URL, включая язык по умолчанию, имеют префикс /[locale]/.

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "fr"],
defaultLocale: "ru",
routing: {
prefixDefaultLocale: false
}
}
})

Это значение по умолчанию. Используйте его, если URL для языка по умолчанию не должны иметь префикс /[locale]/, а сами файлы находятся в корне src/pages/:

  • Директорияsrc
    • Директорияpages
      • about.astro
      • index.astro
      • Директорияen
        • about.astro
        • index.astro
      • Директорияfr
        • about.astro
        • index.astro
  • src/pages/about.astro создаст маршрут example.com/about/
  • src/pages/en/about.astro создаст маршрут example.com/en/about/
astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "fr"],
defaultLocale: "ru",
routing: {
prefixDefaultLocale: true
}
}
})

Используйте эту опцию, если все маршруты должны иметь префикс /locale/ в URL, и все файлы страниц, включая язык по умолчанию, находятся в локализованных папках:

  • Директорияsrc
    • Директорияpages
      • index.astro // Примечание: этот файл обязателен
      • Директорияru
        • index.astro
        • about.astro
      • Директорияen
        • about.astro
        • index.astro
      • Директорияfr
        • about.astro
        • index.astro

Добавлено в: astro@4.2.0

Определяет, будет ли URL главной страницы (/), сгенерированный src/pages/index.astro, перенаправлять на /<defaultLocale>.

При prefixDefaultLocale: true параметр redirectToDefaultLocale также автоматически устанавливается в true. По умолчанию файл src/pages/index.astro будет перенаправлять на главную страницу вашей основной локали.

Вы можете отключить это поведение, установив redirectToDefaultLocale: false. Это позволит иметь главную страницу, находящуюся вне структуры папок локалей.

Добавлено в: astro@4.6.0

При включении этой опции Astro отключит свой мидлвар i18n, чтобы вы могли реализовать собственную логику. Другие параметры routing (например, prefixDefaultLocale) при этом не настраиваются.

Вы будете отвечать за написание собственной логики маршрутизации или ручной запуск мидлвара Astro i18n вместе со своим кодом.

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "fr"],
defaultLocale: "ru",
routing: "manual"
}
})

Astro предоставляет вспомогательные функции для мидлвара, чтобы вы могли управлять маршрутизацией, исключениями, резервным поведением и т. д.: redirectToDefaultLocale(), notFound() и redirectToFallback():

src/middleware.js
import { defineMiddleware } from "astro:middleware";
import { redirectToDefaultLocale } from "astro:i18n"; // доступно при `manual` маршрутизации
export const onRequest = defineMiddleware(async (ctx, next) => {
if (ctx.url.startsWith("/about")) {
return next();
} else {
return redirectToDefaultLocale(302);
}
})

Функция middleware позволяет вручную создать мидлвар i18n Astro. Это дает возможность расширить стандартную маршрутизацию i18n вместо её полной замены.

Вы можете запустить middleware с параметрами маршрутизации в сочетании с собственным мидлваром, используя утилиту sequence для определения порядка выполнения:

src/middleware.js
import { defineMiddleware, sequence } from "astro:middleware";
import { middleware } from "astro:i18n"; // стандартный мидлвар i18n от Astro
export const userMiddleware = defineMiddleware(async (ctx, next) => {
// этот ответ может прийти от мидлвара i18n Astro (например, 404)
const response = await next();
// страница /about — исключение, которую мы хотим отрендерить
if (ctx.url.startsWith("/about")) {
return new Response("Страница О нас", {
status: 200
});
} else {
return response;
}
});
export const onRequest = sequence(
userMiddleware,
middleware({
redirectToDefaultLocale: false,
prefixDefaultLocale: true
})
)

Добавлено в: astro@4.9.0

Эта опция позволяет настраивать домены для каждого языка в проектах с серверным рендерингом (server), использующих адаптеры @astrojs/node или @astrojs/vercel с настроенным параметром site.

Добавьте i18n.domains, чтобы сопоставить поддерживаемые locales с кастомными URL:

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
site: "https://example.com",
output: "server", // обязательно, без пререндеренных страниц
adapter: node({
mode: 'standalone',
}),
i18n: {
locales: ["ru", "en", "fr", "ja"],
defaultLocale: "ru",
routing: {
prefixDefaultLocale: false
},
domains: {
fr: "https://fr.example.com",
en: "https://example.en"
}
}
})

Все несопоставленные локали будут следовать настройке prefixDefaultLocale.

С такой конфигурацией:

  • Файл /fr/about.astro создаст URL https://fr.example.com/about.
  • Файл /en/about.astro создаст URL https://example.en/about.
  • Файл /ja/about.astro создаст URL https://example.com/ja/about.
  • Файл /about.astro создаст URL https://example.com/about.

Эти URL также будут возвращаться функциями getAbsoluteLocaleUrl() и getAbsoluteLocaleUrlList().

Если страница на одном языке не существует (например, ещё не переведена), вместо ошибки 404 вы можете настроить отображение контента из другой локали.

Стратегия резервирования состоит из двух частей: выбора соответствия языков (i18n.fallback) и выбора типа действия — перенаправление или переписывание (rewrite) (i18n.routing.fallbackType, добавлено в Astro v4.15.0).

Например, при i18n.fallback: { fr: "ru" } Astro обеспечит создание страницы в src/pages/fr/ для каждой страницы, существующей в src/pages/ru/.

Если страница в fr отсутствует, она будет создана в зависимости от fallbackType:

  • С перенаправлением на соответствующий маршрут ru (по умолчанию).
  • С контентом из страницы /ru/ (i18n.routing.fallbackType: "rewrite").

В примере ниже ru устанавливается как резервная локаль для пропущенных маршрутов fr. Это значит, что посетитель example.com/fr/my-page/ увидит контент example.com/ru/my-page/ (без перенаправления) вместо страницы 404, если файл src/pages/fr/my-page.astro не существует.

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "fr"],
defaultLocale: "ru",
fallback: {
fr: "ru"
},
routing: {
fallbackType: "rewrite"
}
}
})

Помимо использования строк кода языка (например, “ru”, “en”), Astro позволяет сопоставлять любые коды языков, распознаваемые браузером, с произвольным путём (path) в URL.

Передайте объект в массив locales с ключом path для определения префикса в URL и codes для указания сопоставленных кодов языков. В этом случае имя вашей папки в src/pages/[locale]/ должно точно соответствовать значению path.

Это полезно, если вы поддерживаете несколько вариантов языка (например, "fr", "fr-BR" и "fr-CA") и хотите, чтобы все они были доступны по одному пути /fr/, или если вы хотите полностью кастомизировать путь (например, /french/):

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["ru", "en", "fr"],
locales: ["ru", "en", {
path: "french", // без косых черт
codes: ["fr", "fr-BR", "fr-CA"]
}],
defaultLocale: "ru",
routing: {
prefixDefaultLocale: true
}
}
})

При использовании функций из виртуального модуля astro:i18n используйте path в качестве значения для locale.

У этой функции есть ряд ограничений:

  • Опция site обязательна.
  • Опция output должна быть установлена в "server".
  • Не должно быть отдельных пререндеренных страниц.

Astro полагается на следующие заголовки:

Убедитесь, что ваш хостинг или прокси-сервер передает эти данные. В противном случае возникнет ошибка 404.

Маршрутизация i18n в Astro дает доступ к двум свойствам для определения языка браузера на страницах, рендеримых по запросу: Astro.preferredLocale и Astro.preferredLocaleList. Все страницы, включая статические, имеют доступ к Astro.currentLocale.

Эти свойства объединяют заголовок Accept-Language и ваши настройки locales, чтобы автоматически учитывать предпочтения пользователя.

  • Astro.preferredLocale: Вычисленная предпочтительная локаль пользователя, если она совпадает с одной из локалей в вашем массиве locales. Возвращает undefined, если совпадений нет.

  • Astro.preferredLocaleList: Массив всех локалей, которые одновременно запрошены браузером и поддерживаются вашим сайтом. Если совпадений нет, возвращается []. Если браузер не передает предпочтений, возвращается полный список i18n.locales.

  • Astro.currentLocale: Локаль, вычисленная на основе текущего URL. Если префикс отсутствует, возвращается значение i18n.defaultLocale.

Чтобы сопоставление работало корректно, указывайте codes в том же формате, который использует браузер.