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:
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 ?
I would like to present an alternative i18n libraries which I develop.
lingui-i18n
) and React (lingui-react
)lingui-react
is the only library which fully supports inline components and rich formatting (see below)lingui-cli
) for building message catalogsICU 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
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
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.
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.
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
.