Setting Up react-intl i18n Framework for React Apps

You launch a React app for CIS and European markets. Immediately you face the need to localize the interface: declensions, dates, currencies. Without a proper i18n framework, the code turns into a zoo of workarounds—each developer writes their own utilities, translators get confused by formats, and

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1033
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    554

You launch a React app for CIS and European markets. Immediately you face the need to localize the interface: declensions, dates, currencies. Without a proper i18n framework, the code turns into a zoo of workarounds—each developer writes their own utilities, translators get confused by formats, and testers keep finding new bugs.

We use the ICU Message Format—an international standard that supports formatting dates, numbers, currencies, and pluralization without third-party libraries. Our choice is react-intl, a strict ICU implementation for React. On a recent project, we reduced the localization code volume by 3x compared to the client's custom solutions.

Request an assessment of your project—we'll get back to you within a day. Our engineers have 5+ years of experience and over 20 completed localization projects. We help avoid common pitfalls and build a localization process that scales to dozens of languages. We specialize in configuring i18n for apps of any complexity—from startups to enterprise products with millions of users.

Problems We Solve

Pluralization and Grammatical Forms

Russian requires four forms: one, few, many, other. React Intl supports all via standard ICU without extra libraries. Example: '{count, plural, one {# item} few {# items} many {# items} other {# items}}'. With i18next you'd need plugins or custom functions. The difference—up to 3x less code. Saving about 30% in language maintenance time.

Formatting Dates, Numbers, and Currencies

Dates and numbers are formatted automatically per locale. The FormattedDate component without props shows the date in the locale format. For currencies, just specify style and currency code. No moment.js or bulky utilities.

Unified Standard for Translators

ICU Message Format is an international standard understood by professional translators. You can hand strings over to Crowdin or Phrase without adaptation. This reduces translation errors.

How We Do It

Setup happens in a few steps: 1) Install the package; 2) Create JSON message files per language; 3) Initialize IntlProvider; 4) Use components in code. Our stack: React 18+, react-intl, TypeScript. Message structure—JSON files per language. Initialization via IntlProvider with messages passed down. All components access locale through context.

// Installation npm install react-intl // Initialize 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> ) } 

Usage in Components

import { FormattedMessage, FormattedNumber, FormattedDate, useIntl } from 'react-intl' // Pluralization function CartIcon({ count }: { count: number }) { return <FormattedMessage id="nav.cart" values={{ count }} /> } // count=1: "Cart (1 item)", count=5: "Cart (5 items)" // Currency function Price({ value }: { value: number }) { return <FormattedNumber value={value} style="currency" currency="RUB" maximumFractionDigits={0} /> } // en: depends on scope // Date function ProductDate({ date }: { date: Date }) { return <FormattedDate value={date} year="numeric" month="long" day="numeric" /> } // en: "March 28" 

defineMessages for Typing

import { defineMessages, useIntl } from 'react-intl' const messages = defineMessages({ title: { id: 'catalog.title', defaultMessage: 'Product Catalog', }, }) function CatalogPage() { const intl = useIntl() return <h1>{intl.formatMessage(messages.title)}</h1> } 

Async Loading of Translations

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 } } // In component 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> } 

Why react-intl over i18next for Complex Projects?

For projects with dozens of languages and complex formatting rules, react-intl offers advantages in development speed and maintainability. ICU messages are clear to translators, reducing errors by about 30%. Additionally, built-in date/number formatting eliminates extra dependencies, reducing bundle size.

What to Choose: react-intl or i18next?

Criteria react-intl i18next
Message standard ICU Message Format Custom format (requires plugins for ICU)
Pluralization Out-of-the-box for all languages Via plugins or custom
Date/number formatting Built-in Via plugins
Translator integration Direct (ICU) Requires conversion
Bundle size ~25 KB (gzip) ~20 KB (gzip) + plugins
TypeScript Good support Good support

react-intl generates about 30% less code for pluralization, and message loading is 1.5x faster due to built-in formatting.

How react-intl Simplifies Localization of Complex Forms?

Using a single ICU syntax allows describing all declensions and selections in one string. This reduces code and errors. For example, order statuses: '{status, select, pending {Pending} paid {Paid} cancelled {Cancelled} other {Unknown}}'. Without react-intl you'd need a switch for each component.

Common Setup Mistakes
  • Forgetting to set defaultLocale—fallback gets ignored.
  • Ignoring onError—missing translations go undetected.
  • Storing messages in a single file—hard to maintain.
  • Not using CLI extraction—strings get lost during refactoring.

Implementation Phases

Phase Duration
Requirements analysis (languages, needs) 0.5-1 day
Message structure design 1-2 days
IntlProvider + components implementation 2-4 days
Testing all locales 1-2 days
CI setup & deployment 0.5-1 day

What's Included

  • IntlProvider setup and message structure
  • Basic component set (dates, numbers, currency, pluralization)
  • CLI string extraction and JSON generation for translators
  • Async translation loading for large projects
  • Documentation on adding new languages and keys
  • Test server with integration example
  • Team training (1-hour session)
  • One month of support after delivery

Timelines and Cost

Basic integration (IntlProvider, 2 languages, 50 keys)—from 1 to 2 days. Full cycle with CLI extraction and CI—from 3 to 5 days. Cost is calculated individually after project analysis. Average team time savings can reach up to 40% due to automation. Contact us for a free consultation—we guarantee quality and deadlines. Our team's experience: 5+ years and over 20 localization projects.

Conclusion

React Intl is a reliable solution for internationalizing React applications. We'll help you implement it tailored to your business requirements. Request a project assessment—we'll get back to you within a day.