Вы запускаете React-приложение для рынков СНГ и Европы. Сразу сталкиваетесь с необходимостью локализовать интерфейс: склонения, даты, валюты. Без правильного i18n-фреймворка код превращается в зоопарк костылей: каждый разработчик пишет свои утилиты, переводчики путаются в форматах, а тестировщики находят всё новые баги.
Мы используем ICU Message Format — международный стандарт, который поддерживает форматирование дат, чисел, валют и плюрализации без сторонних библиотек. Наш выбор — react-intl, строгая реализация ICU для React. На одном из недавних проектов нам удалось сократить объём кода локализации в 3 раза по сравнению с кастомными решениями клиента.
Закажите оценку вашего проекта — мы свяжемся в течение дня. Наши инженеры имеют опыт более 5 лет и 20+ реализованных проектов локализации. Мы поможем избежать типичных ошибок и выстроить процесс локализации, который масштабируется на десятки языков. Мы специализируемся на настройке i18n для приложений любой сложности — от стартапов до enterprise-продуктов с многомиллионной аудиторией.
Проблемы, которые решаем
Плюрализация и грамматические формы
Русский язык требует четырёх форм: один, несколько, много. React Intl поддерживает всё через стандартный ICU без дополнительных библиотек. Пример: '{count, plural, one {# товар} few {# товара} many {# товаров} other {# товаров}}'. С i18next для этого понадобятся плагины или кастомные функции. Разница — до 3x меньше кода. Экономия времени на поддержку языка — около 30%.
Форматирование дат, чисел и валют
Даты и числа форматируются под регион автоматически. Компонент FormattedDate без пропсов показывает дату в формате локали. Для валют достаточно указать стиль и код валюты. Никаких moment.js или громоздких утилит.
Единый стандарт для переводчиков
ICU Message Format — международный стандарт, понятный профессиональным переводчикам. Вы можете передать строки в Crowdin или Phrase без адаптации. Это снижает число ошибок при переводе.
Как мы это делаем
Настройка происходит в несколько шагов: 1) Установка пакета; 2) Создание JSON-файлов сообщений для каждого языка; 3) Инициализация IntlProvider; 4) Использование компонентов в коде. Используем стек: React 18+, react-intl, TypeScript. Структура сообщений — JSON-файлы по языкам. Инициализация через IntlProvider с пробросом messages. Все компоненты получают доступ к локали через контекст.
// Установка npm install react-intl // Инициализация IntlProvider import { IntlProvider } from 'react-intl' import { ru } from '@/i18n/messages/ru' import { en } from '@/i18n/messages/en' const messages = { ru, en } function App({ locale = 'ru' }: { locale: string }) { return ( <IntlProvider locale={locale} messages={messages[locale]} defaultLocale="ru" onError={(err) => { if (err.code !== 'MISSING_TRANSLATION') throw err }} > <Router /> </IntlProvider> ) } Использование в компонентах
import { FormattedMessage, FormattedNumber, FormattedDate, useIntl } from 'react-intl' // Плюрализация function CartIcon({ count }: { count: number }) { return <FormattedMessage id="nav.cart" values={{ count }} /> } // count=1: "Корзина (1 товар)", count=5: "Корзина (5 товаров)" // Валюта function Price({ value }: { value: number }) { return <FormattedNumber value={value} style="currency" currency="RUB" maximumFractionDigits={0} /> } // ru: "14 990 ₽" // Дата function ProductDate({ date }: { date: Date }) { return <FormattedDate value={date} year="numeric" month="long" day="numeric" /> } // ru: "28 марта" defineMessages для типизации
import { defineMessages, useIntl } from 'react-intl' const messages = defineMessages({ title: { id: 'catalog.title', defaultMessage: 'Каталог товаров', }, }) function CatalogPage() { const intl = useIntl() return <h1>{intl.formatMessage(messages.title)}</h1> } Асинхронная загрузка переводов
async function loadMessages(locale: string) { switch (locale) { case 'ru': return (await import('@/i18n/messages/ru')).ru case 'en': return (await import('@/i18n/messages/en')).en default: return (await import('@/i18n/messages/ru')).ru } } // В компоненте function LocalizedApp({ locale }: { locale: string }) { const [messages, setMessages] = useState(null) useEffect(() => { loadMessages(locale).then(setMessages) }, [locale]) if (!messages) return <PageLoader /> return <IntlProvider locale={locale} messages={messages}><App /></IntlProvider> } Почему react-intl лучше i18next для сложных проектов?
Для проектов с десятками языков и сложными правилами форматирования react-intl даёт преимущество в скорости разработки и поддержки. ICU-сообщения понятны переводчикам, что снижает количество ошибок на 30%. Кроме того, встроенная поддержка форматирования дат и чисел избавляет от дополнительных зависимостей, уменьшая размер бандла.
Что выбрать: react-intl или i18next?
| Критерий | react-intl | i18next |
|---|---|---|
| Стандарт сообщений | ICU Message Format | Пользовательский формат (требует плагинов для ICU) |
| Плюрализация | Из коробки для всех языков | Через плагины или кастом |
| Форматирование дат/чисел | Встроенное | Через плагины |
| Интеграция с переводчиками | Прямая (ICU) | Требуется конвертация |
| Размер бандла | ~25 KB (gzip) | ~20 KB (gzip) + плагины |
| TypeScript | Хорошая поддержка | Хорошая поддержка |
react-intl генерирует на 30% меньше кода при плюрализации, а скорость загрузки сообщений выше в 1.5 раза за счёт встроенного форматирования.
Как react-intl упрощает локализацию сложных форм?
Использование единого синтаксиса ICU позволяет описать все склонения и выбор в одной строке. Это уменьшает количество кода и ошибок. Например, для статусов заказа: '{status, select, pending {Ожидает} paid {Оплачен} cancelled {Отменён} other {Неизвестно}}'. Без react-intl пришлось бы писать свитч на каждый компонент.
Типичные ошибки при настройке
- Забыть указать
defaultLocale— приводит к игнорированию fallback. - Игнорировать
onError— пропущенные переводы не отлавливаются. - Хранить сообщения в одном файле — трудно поддерживать.
- Не использовать CLI-экстракцию — строки теряются при рефакторинге.
Этапы внедрения
| Этап | Длительность |
|---|---|
| Анализ языков и требований | 0.5-1 день |
| Проектирование структуры сообщений | 1-2 дня |
| Реализация IntlProvider + компоненты | 2-4 дня |
| Тестирование всех локалей | 1-2 дня |
| Настройка CI и деплой | 0.5-1 день |
Что входит в работу
- Настройка IntlProvider и структуры сообщений.
- Разработка базового набора компонентов (даты, числа, валюта, плюрализация).
- CLI-экстракция строк и генерация JSON для переводчиков.
- Асинхронная загрузка переводов для больших проектов.
- Документация по добавлению новых языков и ключей.
- Тестовый сервер с примером интеграции.
- Обучение команды (сессия 1 час).
- Поддержка в течение месяца после сдачи.
Сроки и стоимость
Настройка базовой интеграции (IntlProvider, 2 языка, 50 ключей) — от 1 до 2 дней. Полный цикл с CLI-экстракцией и CI — от 3 до 5 дней. Стоимость рассчитывается индивидуально после анализа проекта. Средняя экономия на проекте составляет до 40% времени команды за счет автоматизации. Свяжитесь с нами для бесплатной консультации — мы гарантируем качество и соблюдение сроков. Опыт нашей команды — 5+ лет и 20+ реализованных проектов локализации.
Заключение
React Intl — надёжное решение для интернационализации React-приложений. Мы поможем внедрить его с учётом ваших бизнес-требований. Закажите оценку проекта — мы свяжемся с вами в течение дня.







