LingoProvider — это React-контекст, в котором хранятся активная локаль и карта сообщений. Достаточно один раз обернуть им корень приложения — и всё внутри сможет вызывать useLingo(), чтобы переводить строки и получать метаданные локали.
Базовое использование#
import { LingoProvider } from "@lingo.dev/react";
import messages from "./locales/es.json";
<LingoProvider locale="es" messages={messages}>
<App />
</LingoProvider>Свойства#
| Свойство | Тип | Обязательно | Назначение |
|---|---|---|---|
locale | string | да | Тег BCP-47, например "en", "es", "ar-SA". Определяет всё форматирование и распознавание RTL. |
messages | Messages | нет | Переводы с ключами на основе хеша. По умолчанию — {} (всё будет браться из исходного текста). |
children | ReactNode | да | Ваше приложение. |
Messages — это просто Record<string, string> в том же формате, в котором CLI записывает данные в locales/<locale>.json.
Вложенные провайдеры#
Провайдеры можно вкладывать друг в друга. Правила зависят от того, совпадает ли локаль вложенного провайдера с локалью родительского или отличается от неё.
Одинаковая локаль — сообщения объединяются#
<LingoProvider locale="es" messages={sharedMessages}>
{/* Route-scoped messages override shared on collision; missing keys fall through to shared. */}
<LingoProvider locale="es" messages={dashboardMessages}>
<Dashboard />
</LingoProvider>
</LingoProvider>Это удобно, если вы делите бандлы по маршрутам, но хотите сохранить общий набор переводов для «оболочки» в корне приложения.
Разные локали — изолированная работа#
<LingoProvider locale="es" messages={esMessages}>
<Header />
<LingoProvider locale="ar-SA" messages={arMessages}>
{/* This subtree is entirely Arabic; the parent's es messages are NOT visible. */}
<ArabicEmbed />
</LingoProvider>
</LingoProvider>Удобно, если нужно отрендерить отдельный компонент на фиксированном языке — например, цитату, встраиваемый блок или панель предпросмотра — внутри приложения с другой локалью.
Переключение локали во время выполнения#
Относитесь к locale как к состоянию React: измените его — и все потребители useLingo() ниже по дереву перерендерятся с новой локалью и новым набором сообщений.
function AppRoot() {
const [locale, setLocale] = useState("en");
const [messages, setMessages] = useState({});
async function switchTo(next: string) {
const next_messages = await import(`./locales/${next}.json`);
setLocale(next);
setMessages(next_messages.default);
}
return (
<LingoProvider locale={locale} messages={messages}>
<LocaleSwitcher current={locale} onSelect={switchTo} />
<App />
</LingoProvider>
);
}В Next.js предпочтительнее использовать useLocaleSwitch() из @lingo.dev/react-next — он учитывает роутер при смене локали и отвечает за её сохранение.
Что можно получить из контекста#
useLingo() возвращает активный объект Lingo. Помимо text() и rich(), в нём есть:
locale— переданная вами строка BCP-47direction—"ltr"или"rtl"; вычисляется черезIntl.Locale.textInfo, а если это не сработает, используется резервный список известных RTL-языковscript— например,"Latn","Cyrl","Arab"region— например,"US","DE","SA"
Это полезно для условной вёрстки — например, чтобы зеркалить иконки в RTL, — или для тегирования аналитики: ничего дополнительно разбирать не нужно.
Распространённые ошибки#
- Забыть про
<LingoProvider>. Вне негоuseLingo()выбросит ошибку. Текст ошибки подскажет добавить провайдер; если вы видите это в тестах, оберните рендер в провайдер тестового режима с пустымmessages, чтобы проверки оставались стабильными. - Передавать напрямую асинхронно загруженные сообщения.
messagesдолжен быть Синхронный значением. Сначала разрешите промис в родительском компоненте (через Suspense или state), а затем передайте результат ниже. - Менять
localeбез обновленияmessages. Провайдер воспринимает оба свойства как связанную пару — обновляйте их в рамках одного измененияuseState, иначе на короткое время получите новую локаль со старыми переводами.
