Search code examples
javascriptreactjsinternationalizationreact-intlreact-i18next

react-intl vs react-i18next for ReactJS internationalization (i18n)


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:

react-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 ?


Solution

  • 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.