Разрабатывая продукт, в какой-то момент задумываешься о поддержке языков. И, казалось бы, что могло пойти не так? Давайте посмотрим, какие инструменты и библиотеки существуют, и что у них под капотом: Не самое популярное решение и на то есть причины, использование выглядит примерно так: Плюсы: Простой API Маленький вес (6.7kB) Минусы: При переключении языков автоматически не обновляются компоненты, нужно писать свою обертку Нет поддержки асинхронной подгрузки переводов, вручную добавлять можно, но это, опять же, дополнительная сложность Нет полноценной поддержки фолбеков, если в текущей локали не найден перевод Под капотом используется localized-strings. Пожалуй, самое популярное и распространенное решения для локализации. Использование выглядит так: Плюсы: Большое комьюнити Множество плагинов, которые позволяют, например, использовать асинхронную подгрузку других локалей Автоматическое обновление компонентов при смене языка Поддержка concurrent features (React 18), для упрощения работы с асинхронными манипуляциями Минусы: Весит 20.1 kB, но не дайте себя обмануть! Для его работы требуется i18next, который добавляет 54.5 kB, и того мы имеем 74.6 kB Каждый плагин добавляет дополнительный вес вашему бандлу Из примера использования понятно, что использует i18next. Плюсы: Простое API Маленький вес (6.6 kB) Поддерживает асинхронную загрузку, правда, не обойдется без дополнительного кода Есть плагины, для более удобного использования, например, для автоматического определения языка Минусы: Все удобные инструменты находятся в @lingui/macro, которые не понятно сколько на самом деле весят, так как там используются макросы babel Достаточно распространенное решение, так как использует нативные методы форматирования и предоставляет полифилы для них. Плюсы: Поддерживает AST для переводов (подробнее в документации), с помощью которого можно уменьшить вес конечного бандла Минусы: Для переключения языков нужно реализовывать свою обертку Большой вес (56.7 kB) Имеет собственную достаточно специфичную реализацию форматирования Под капотом использует formatjs. Без рисков и излишнего бойлерплейта выбор падает на react-i18next, но не поймите меня не правильно, это не чистое решение в экосистеме React, да и вес оставляет желать лучшего. Давайте сформируем функциональные требования к библиотеке для локализации: Поддержка асинхронной загрузки переводов, без бойлерплейта и специфичных решений, чтобы не грузить на клиент все переводы сразу и не раздувать тем самым бандл Соответственно, поддержка лоадера или скелетона, пока загружается перевод Удобный способ переключения между языками и автоматическое переключение на текущую локаль в компонентах Поддержка фолбеков, если в текущем переводе не нашлось перевода Поддержка шаблонизации, например, чтобы вставлять имя пользователя в строку с переводом Из хотелок можно выделить поддержку вложенных переводов для человекопонятой структуризации, то бишь, например, main.header.title и предзагрузку переводов. Поддерживается передача любого компонента в качестве лоадера или скелетона: Передача всех переданных поддерживаемых языков: Предзагрузка перевода отличного от текущего: Использование concurrent features из React 18, которые позволяют показывать предыдущий перевод, вместо лоадера, при смене языка: Поддержка шаблонизации: Кто-то может возразить, а как же форматирование дат? Как реализовать пруализацию? Все проще, чем кажется: во-первых, можно реализовать через шаблонизацию, во-вторых, у всех встроенных типов, будь то Date или Number, есть методы toLocaleString и подобные, в которые можно передать свой язык, а не только установленный по-умолчанию в браузере. Через шаблонизацию: Через встроенный метод: По поводу поддержки браузерами можно посмотреть caniuse — там все очень хорошо. Что касается поддержки множественных чисел, то тут тоже все просто: react-localization react-i18next @lingui/react react-intl i18nano Старый