React Intl: интернационализация React-приложений

TL;DR
React Intl — библиотека для i18n в React. Она даёт провайдер переводов и готовые компоненты для вывода локализованных строк, чисел и дат. Установите пакет, подготовьте файлы переводов и оберните корень приложения в IntlProvider; для вставки строк используйте FormattedMessage, для чисел — FormattedNumber, для дат — FormattedDate.
Введение
React Intl — популярная библиотека, которая предоставляет компоненты и утилиты для интернационализации React-приложений. Интернационализация (i18n) — это процесс адаптации приложения под разные языки и культурные особенности: форматы дат, чисел, валют, порядок слов и склонения.
В этом руководстве вы найдёте пошаговые инструкции, примеры кода и рекомендации по хорошим практикам. Также внизу — чек-листы для ролей, сценарии ошибок и варианты альтернатив.
Ключевые термины (одной строкой)
- i18n: интернационализация — подготовка к переводам и локалям.
- Локаль: языково-культурная конфигурация (например, en-US, fr, ru).
- Сообщение/Message: ключ–значение перевода, может содержать параметры (placeholders).
- ICU: формат сообщений для сложных правил (плюралы, варианты).
Установка React Intl
React Intl устанавливается как npm-пакет. Поддерживаются npm, yarn и pnpm. Выполните команду в терминале в корне проекта.
Примеры команд:
npm install react-intlили
yarn add react-intlили
pnpm add react-intlВажно: проверяйте совместимость версии React и react-intl в changelog перед апгрейдом.
Структура файлов переводов
Один из распространённых подходов — хранить один файл переводов на локаль. Структура может быть такой:
- src/locales/en.json
- src/locales/fr.json
- src/locales/ru.json
Пример простого файла переводов в формате ES-модуля:
export const messagesInFrench = {
greeting: "Bonjour {name}"
}
export const messagesInItalian = {
greeting: "Buongiorno {name}"
}Вы также можете использовать JSON-файлы или динамическую загрузку (code-splitting) переводов.
Как подключить IntlProvider
IntlProvider предоставляет локаль и набор сообщений (messages) всему приложению через контекст.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { IntlProvider } from "react-intl";
import { messagesInFrench } from "./translation";
ReactDOM.createRoot(document.getElementById("root")).render(
);Параметры IntlProvider:
- locale — текущая локаль (строка).
- messages — объект переводов для локали.
- defaultLocale — локаль по умолчанию, если перевод отсутствует.
Совет: автоматически определяйте locale по языку браузера, но храните явный fallback.
Форматирование переводов: FormattedMessage
Для вывода перевода используйте компонент FormattedMessage. Он ищет id в объекте messages и подставляет значения.
import React from "react";
import { FormattedMessage } from "react-intl";
function App() {
return (
);
}
export default App;Примечания:
- defaultMessage используется как запасной текст и может служить источником для автоматического извлечения ключей.
- values — объект значений для placeholder’ов.
- Для сложных правил используйте ICU-синтаксис (плюралы, выбор). Пример плюралов:
messages = {
inbox: "You have {count, plural, one {# message} other {# messages}}"
}Форматирование чисел: FormattedNumber
FormattedNumber форматирует числа в соответствии с локалью. Можно задать стиль, валюту и точность.
import React from "react";
import { FormattedNumber } from "react-intl";
function App() {
return (
Decimal:
Percent:
);
}
export default App;Пример форматирования валюты:
import React from "react";
import { FormattedNumber } from "react-intl";
function App() {
return (
Price:
);
}
export default App;Опции minimumFractionDigits и maximumFractionDigits контролируют количество знаков после запятой.
Форматирование дат и времени: FormattedDate
FormattedDate (и более общий FormattedDate/Time API) позволяет выводить даты и время в локализованном виде.
import React from "react";
import { FormattedDate } from "react-intl";
function App() {
const today = new Date();
return (
Today's date is
);
}
export default App;Поддерживаемые опции:
- year: “numeric” или “2-digit”
- month: “numeric”, “2-digit”, “narrow”, “short”, “long”
- day: “numeric” или “2-digit”
- hour/minute/second: “numeric” или “2-digit”
- timeZoneName: “short” или “long”
Для форматирования только времени используйте hour/minute/second.
Практические рекомендации и лучшие практики
- Держите ключи сообщений семантичными и неизменными (например, onboarding.welcome). Не используйте исходный английский текст как ключ.
- Разделяйте контентные и технические ключи. Текст должен быть читаем для переводчика.
- Избегайте конкатенации строк в коде — используйте placeholders.
- Используйте ICU для плюралов и сложных вариантов.
- Стратегия загрузки: лениво загружайте файлы переводов для экономии трафика.
- Тестируйте локали с длинными строками (немецкий) и короткими (китайский).
- Учтите направление письма (ltr/rtl) — измените CSS и layout при необходимости.
Типичные ошибки и способы их устранения
- Необновлённый state после смены locale: обновляйте контекст IntlProvider или принудительно ререндерьте корень приложения.
- Отсутствие fallback для переводов — используйте defaultLocale и defaultMessage.
- Хардкодинг форматов дат и чисел — опирайтесь на API локализации.
- Неполные или неоднозначные ключи переводов — добавьте контекст для переводчиков.
Когда React Intl может не подойти
- Если у вас очень небольшое приложение с одноразовым переводом, сложная библиотека может быть избыточна.
- Для приложений с критичными требованиями к size bundle, где нельзя добавить внешнюю зависимость, рассмотрите встроенный Intl API и собственные простые обёртки.
- Если нужно очень адаптивное форматирование на сервере (SSR) с pre-rendering без дополнительных настроек — потребуется дополнительная конфигурация.
Альтернативы и сравнение (кратко)
- react-i18next — популярная альтернатива, ориентированная на JSON-файлы, lazy-loading и экосистему i18next.
- Использование нативного Intl API — лёгкий вариант, но без готовых компонентов и message management.
- LinguiJS — подход, близкий к React Intl, но с собственным инструментарием для извлечения сообщений.
Мини-методология внедрения i18n (шаги)
- Определите требуемые локали и поля переводов.
- Структурируйте каталоги локалей (по языку или фичам).
- Подключите IntlProvider в корне приложения.
- Замените хардкодные строки на FormattedMessage.
- Настройте автотесты и проверки на отсутствие незаполненных ключей.
- Организуйте процесс перевода (CSV/PO/сервис переводов).
Рольные чек-листы
Разработчик:
- Обернуть приложение IntlProvider.
- Заменить строки на FormattedMessage.
- Обеспечить lazy-loading переводов.
Дизайнер:
- Проверить растяжение текста для длинных переводов.
- Убедиться, что интерфейс корректно поддерживает rtl, если нужно.
Менеджер контента/переводчик:
- Предоставить контекст и примеры использования.
- Заполнить все ключи и протестировать сборки.
Критерии приёмки
- Все пользовательские строки вынесены в переводы.
- Для каждой локали есть fallback.
- Форматы дат и чисел корректны для локали.
- Нет конкатенированных фраз, которые ломают грамматику при переводе.
Плейбук на случай проблем с переводами
- Проверить, что messages загружаются (network tab).
- Убедиться, что locale совпадает с ключами в messages.
- Если перевод пустой — проверить defaultMessage.
- При ошибках ICU — запустить проверку синтаксиса сообщений.
- Откат: вернуть предыдущую версию translation-файлов и redeploy.
Примеры тест-кейсов и приёмки
- Изменить locale в настройках пользователя и убедиться, что все видимые строки изменились.
- Открыть страницу с датой/числом и проверить соответствие локали (например, 1 234,56 vs 1,234.56).
- Проверить поведение при отсутствии translations (используется defaultMessage).
Шпаргалка (cheat sheet)
- IntlProvider: locale, messages, defaultLocale.
- FormattedMessage: id, defaultMessage, values.
- FormattedNumber: value, style, currency, minimumFractionDigits, maximumFractionDigits.
- FormattedDate: value, year, month, day, hour, minute, second, timeZoneName.
Факт-бокс: что нужно помнить
- Форматы дат/чисел зависят от локали пользователя.
- ICU-синтаксис покрывает плюралы и варианты.
- Поддержка RTL требует изменений в CSS и layout.
- Переводы лучше хранить отдельно и загружать по требованию.
Миграция: советы
- Мигрируйте постепенно, компонент за компонентом.
- Начните с ключевых потоков (onboarding, checkout).
- Параллельно настраивайте систему сборки и pipeline переводов.
Примеры ошибок и способы проверки
- Ошибка: пустые сообщения после сборки — проверьте, что файлы переводов включены в сборку (webpack/rollup config).
- Ошибка: некорректные ICU-формулы — используйте линтер сообщений или специализированный валидатор.
Пример decision flowchart для выбора локали
flowchart TD
A[Начало: определить локаль] --> B{Пользователь указал язык в профиле?}
B -- Да --> C[Использовать указанный язык]
B -- Нет --> D{Язык в браузере определён?}
D -- Да --> E[Использовать язык браузера]
D -- Нет --> F[Использовать defaultLocale приложения]
C --> G[Загрузить соответствующие messages]
E --> G
F --> G
G --> H[Render IntlProvider]Безопасность и приватность
Переводы обычно не содержат персональных данных. Тем не менее избегайте вставки чувствительных данных в сообщения без шифрования/маскировки.
Локальные особенности и советы для России
- Валюта: RUB, используйте стиль currency и явно указывайте currencyDisplay, если нужно.
- Формат дат в России часто «дд.мм.гггг» — при необходимости используйте локализационные опции или собственное форматирование.
- Проверяйте падежи и склонения для динамических вставок; иногда требуется более сложный ICU или подготовка нескольких форм сообщений.
Заключение
React Intl упрощает интернационализацию: он предоставляет API для переводов и локализованного форматирования чисел и дат. Начните с установки и оборачивания приложения в IntlProvider, затем последовательно заменяйте хардкодные строки на FormattedMessage и применяйте FormattedNumber/FormattedDate там, где это требуется. Тестируйте локали, планируйте процесс перевода и контролируйте качество сообщений.
Важное: начните с малого — ключевые пользовательские пути — и расширяйте покрытие переводами по мере роста продукта.
Краткое резюме:
- Настройте IntlProvider с locale и messages.
- Используйте FormattedMessage, FormattedNumber и FormattedDate.
- Применяйте ICU для плюралов и сложной логики.
Похожие материалы
Ускорить медленный SSD в Windows 11
OneNote: создание, обмен и переключение блокнотов
Apple Sports на iPhone — руководство и советы
Играть в Pokémon на Android через RetroArch
Защита SIM‑карты: угрозы и меры