Using with ICU format

i18next itself is flexible enough to support multiple existing i18next formats beside its own. So also the ICU format, thanks to i18next-icu.

Find the full working sample here.

Extend the i18n instance with ICU module

To enable ICU format you will need to include the i18next-icu module into your i18next instance.

Use the ICU format

using t function

using the Trans Component

Using ICU syntax is not possible within a JSX node because {curly brackets} are reserved for interpolation.

To work around this, you can use the IcuTrans Component directly like this:

While this works the resulting JSX is very verbose and prone to errors. Let's use a babel macro to provide more intuitive syntax!

using babel macros (Trans, Plural, Select)

Thanks to using kentcdodds/babel-plugin-macros we could use some babel magic to transpile nicer looking jsx to above Trans markup.

Check https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md for setting babel-plugin-macros up.

Using create-react-app? Make sure you are using react-scripts v2 as it includes the macro plugin.

The macro will add the needed import for the IcuTrans Component and generate the correct IcuTrans component for you.

The correct string for translations will be shown in the browser console output as a missing string (if set debug: true on i18next init) or submitted via saveMissing (have saveMissing set true and a i18next backend supporting saving missing keys).

The defaults parsing supports the @babel/react preset, so any expressions that require more complex parsing may not work.

More samples:

Tagged Template for ICU

To support complex interpolations, react-i18next provides additional imports from the icu.macro. These provide a way to represent translations closer to the ICU messageformat syntax, but in a manner that is compatible with React and strictly typed in typescript.

For example, to format a number:

the above syntax, although valid javascript, will error when using a linting tool like eslint. Instead, we can do this:

This results in the translation string Incremented {num, number} times

Supported interpolators are number, date, time, select, plural, and selectOrdinal.

More complex skeletons can also be represented:

This results in the translation string It's awesome {awesomePercentage, number, ::percent} of the time.

Complex interpolations with plural/select/selectOrdinal

The plural and select and selectOrdinal interpolations support more advanced syntax. For instance, it is possible to interpolate both React elements and other interpolations:

This will result in the translation string {awesomePercentage, plural, =0 { It's <0>never&lt;/0&gt; awesome } =100 { It is <1>ALWAYS&lt;/1&gt; awesome! } =100 { It's awesome {awesomePercentage, number, ::percent} of the time }}

It possible to nest any interpolated type, including nested plural, select, or selectOrdinal.

Typescript support for interpolated template strings

The number, plural, and selectOrdinal functions will error if a non-number typed variable is interpolated.

The date and time functions will error if a non-Date object is interpolated.

Finally, the select function will error if a non-string is interpolated.

Alternative syntax for select and plural

It is also possible to display select and plural and selectOrdinal using Elements Select, Plural and SelectOrdinal. All of them have full type safety in typescript.

Select

There is no way to directly add the needed ICU format inside a JSX child - so we had to add another component that gets transpiled to needed Trans component:

Plural

SelectOrdinal

The needed plural forms can be looked up in the official unicode cldr table: http://www.unicode.org/cldr/charts/33/supplemental/language_plural_rules.html

In addition to the plural forms you can specify results for given number values like show above:

0="show if zero"

in ICU it would be =0 {show if zero} but = is not allowed to be leading char in attributes so we replaced it with $

Last updated