42

I need to build a multilanguage application using ReactJS. The application needs a custom dictionary for different languages as well as automatic formatting of date/time, numbers and currency.

From all I´ve seen there are 2 very popular libraries:

reac-intl and react-i18next

What would be the advantages between one and another ? What is the most supported and popular one ?

What is the general choice for a ReactJS application supporting multiple languages ?

Mendes
  • 13,757
  • 24
  • 122
  • 217
  • 4
    The main developer for react-intl left Yahoo for Apple in March and doesn't seem to be involved any longer. The status of the project seems unclear. – mikebridge May 09 '17 at 05:46
  • 1
    3 years later, react-intl seems to be going strong. – Ryall Apr 22 '20 at 10:49

3 Answers3

25

js-lingui

I would like to present an alternative i18n libraries which I develop.

  • works both with Vanilla JS (lingui-i18n) and React (lingui-react)
  • lingui-react is the only library which fully supports inline components and rich formatting (see below)
  • build on top of ICU MessageFormat
  • includes also CLI (lingui-cli) for building message catalogs
  • it uses Flow types and a lot of validation during compile time to catch obvious errors in MessageFormat

Syntax

ICU MessageFormat is very flexible as it supports variables, plurals, ordinals, choices, number/date formatting and is also extensible. However, complex messages are a bit difficult to write.

lingui-i18n provides convenient syntax using ES6 tagged template literals, while lingui-react provides similar syntax using React Components

Vanilla JS

import { i18n } from 'lingui-i18n'

i18n.t`Hello World`
i18n.t`Hello, my name is ${name}`
i18n.plural({ value: count, one: "# book", other: "# books" })

More examples in lingui-i18n docs

React

import React from 'react'
import { Trans, Plural } from 'lingui-react'

class App extends React.Component {
  render() {
    const name = "Fred"
    const count = 42

    return (
      <div>
      // Static text
      <Trans>January</Trans>

      // Variables
      <Trans>Hello, my name is {name}</Trans>

      // Components
      <Trans>See the <a href="/more">description</a> below.</Trans>

      // Plurals
      <Plural 
        value={count} 
        zero={<strong>No books</strong>}
        one="# book" 
        other="# books" 
      />
      </div>
    )
  }
}

docs are part of js-lingui main docs.

Inline components and rich formatting

I started writing this lib because I wanted a) easier syntax and b) full support for inline components.

Both react-intl and react-i18next have very limited support for rich text and inline components. You can either use basic html tags inside components (This is <strong>bold</strong> text.) or inject components as variables (This is {el} text. where el = <strong>bold</strong>).

The problem with the 1st approach is that you can't use custom React components. The problem with the 2nd approach is that translator works with 2 messages instead of one (This is {el} text. and bold). This is actually pretty bad because you need to translate the whole sentence to keep context.

With lingui-react you can use any React components inside translations and the message is extracted in one piece:

<Trans>See the <Link to="/more">description</Link> below.</Trans>
// for translator: See the <0>description</0> below.

Another advantage of this solution is that component name and props are hidden in extracted message. I remember how we spent a lot of time updating translations only after we changed class on the inner element.

Just compare it with interpolation in react-i18next or react-intl.

Requirements

Both lingui-i18n and lingui-react require presets to make everything work. This is a problem if you want to use it with Create React App as you need to either eject or fork react-scripts.

Tomáš Ehrlich
  • 5,738
  • 2
  • 21
  • 30
  • Very interesting analysis, but this is not correct anymore, react-i18next now provide the two feature you speak about: full component interpolation and messages extraction take a look at https://react.i18next.com/components/trans-component – DevTheJo May 19 '18 at 14:39
  • If you don't want to eject. You can use craco to add webpack configuration: https://www.npmjs.com/package/@craco/craco – Mohamed Allal Feb 03 '19 at 15:10
  • 2
    @Jo-Go the correct link to the documentation is now: https://react.i18next.com/latest/trans-component – Alp Oct 14 '19 at 15:04
9

The general choice is react-intl, which is widely more popular than react-i18next. It currently has 4.5k vs react-i18next's 300 stars on github. It is the go-to solution for localization in React.

Here's a tutorial to get started: https://medium.freecodecamp.com/internationalization-in-react-7264738274a0

whyp
  • 567
  • 3
  • 12
  • 1
    https://medium.com/@jamuhl/i18n-frameworks-the-unfair-showdown-8d436cd6f470 https://www.i18next.com/overview/comparison-to-others – Mohamed Allal Feb 03 '19 at 15:24
  • 1
    GitHub stars are a bad indicator of popularity. https://www.npmtrends.com/react-intl-vs-react-i18next The actual usage numbers are almost identical. – Sam Bokai Jan 18 '21 at 23:06
  • 2
    @SamBokai Looking at the graph your posted, at the time of writing there was a 12x difference (73k to 6k) in favor of react-intl. Since then react-i18next did a tremendous job of catching up. – whyp Jan 19 '21 at 04:51
  • @whyp Good point! – Sam Bokai Jan 19 '21 at 09:59
3

Try https://github.com/alibaba/react-intl-universal which is developed by Alibaba Group. yahoo/react-intl can only be applied in view layer such as React.Component. For Vanilla JS file, there’s no way to internationalize it. For example, the following snippet is general form validator used by many React.Component in our apps.

export default const rules = {
  noSpace(value) {
    if (value.includes(' ')) {
      return 'Space is not allowed.';
    }
  }
};

alibaba/react-intl-universal is simple but powerful. It doesn’t change behavior of components. And can used in JSX and normal JS file.

cwtuan
  • 1,361
  • 1
  • 13
  • 15