What is react-i18next?
The react-i18next package is a powerful internationalization framework for React / React Native which is based on i18next. It provides a way to translate your application into multiple languages, handle plurals and formatting, and manage translations.
What are react-i18next's main functionalities?
Translation
This feature allows you to translate text in your React components using the `t` function provided by the `useTranslation` hook.
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <p>{t('keyForTranslation')}</p>;
}
Language Switching
This feature enables you to switch languages on the fly within your application by calling the `changeLanguage` method.
import { useTranslation } from 'react-i18next';
function ChangeLanguageButton() {
const { i18n } = useTranslation();
return (
<button onClick={() => i18n.changeLanguage('de')}>Change to German</button>
);
}
Pluralization
This feature allows you to handle plural forms in translations depending on the count provided.
import { useTranslation } from 'react-i18next';
function MyComponent({ count }) {
const { t } = useTranslation();
return <p>{t('keyForPlural', { count })}</p>;
}
Formatting
This feature allows you to format dates, numbers, and other values within your translations.
import { useTranslation } from 'react-i18next';
function MyComponent({ date, number }) {
const { t } = useTranslation();
return (
<div>
<p>{t('formattedDate', { date })}</p>
<p>{t('formattedNumber', { number })}</p>
</div>
);
}
Namespaces
This feature allows you to organize your translations into namespaces, making it easier to manage large translation files.
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation('namespace1');
return <p>{t('namespace1:keyForTranslation')}</p>;
}
Other packages similar to react-i18next
lingui-react
LinguiJS is a readable, automated, and optimized (5 kb) internationalization for JavaScript. It is similar to react-i18next but uses a different API and has its own macro syntax for defining translations.
react-intl
React Intl is part of FormatJS which provides internationalization support for React applications. It is similar to react-i18next in providing translations and formatting but uses a different API, including components like <FormattedMessage> and <FormattedNumber>.
react-translate-component
This package provides a component for React that utilizes the Counterpart translation library. It is less feature-rich compared to react-i18next and is more suitable for simpler applications that do not require advanced features like pluralization or namespace support.
react-localize-redux
React Localize Redux provides localization support for React/Redux applications. It integrates with Redux for state management of translations and locale data, which is different from react-i18next's approach of using the i18next framework.
react-i18next
Higher-order components and components for React when using i18next.
Installation
Source can be loaded via npm, bower or downloaded from this repo.
# npm package
$ npm install react-i18next
# bower
$ bower install react-i18next
- If you don't use a module loader it will be added to
window.reactI18next
Examples
Requirements
- react >= 0.14.0
- i18next >= 2.0.0
I18nextProvider
It will add your i18n instance in context.
import React from 'react';
import ReactDOM from 'react-dom';
import { I18nextProvider } from 'react-i18next';
import App from './App';
import i18n from './i18n';
ReactDOM.render(
<I18nextProvider i18n={ i18n }><App /></I18nextProvider>,
document.getElementById('app')
);
Translate HOC
translate(namespaces, options): higher-order component to wrap a translatable component.
- All given namespaces will be loaded.
- props.t will default to first namespace in array of given namespaces (providing a string as namespace will convert automatically to array, providing no namespaces will default to
defaultNS
) - used nested inside I18nextProvider (context.i18n)
- passing
{ withRef: true }
to options store a ref to the wrapped component instance making it available via getWrappedInstance()
method - passing
{ translateFuncName: 'someFunctionName' }
will change the name of the property passed to the child component for the translation function (by default, the value is t
). This is useful if you are already using a concrete function name for extracting the translation chains from your source files
import React from 'react';
import { translate } from 'react-i18next';
function TranslatableView(props) {
const { t } = props;
return (
<div>
<h1>{t('keyFromDefault')}</h1>
<p>{t('anotherNamespace:key.from.another.namespace', { /* options t options */ })}</p>
</div>
)
}
export default translate(['defaultNamespace', 'anotherNamespace'])(TranslatableView);
You can set options.wait to true if you want to delay rendering until translation files are loaded:
import React from 'react';
import { translate } from 'react-i18next';
function TranslatableView(props) {
const { t } = props;
return (
<div>
<h1>{t('keyFromDefault')}</h1>
<p>{t('anotherNamespace:key.from.another.namespace', { /* options t options */ })}</p>
</div>
)
}
export default translate(['defaultNamespace', 'anotherNamespace'], { wait: true })(TranslatableView);
getWrappedInstance(): allows you to access to the component instance, wrapped into translate()
.
Only available if you pass { withRef: true }
to the translate()
options.
import React, { Component } from 'react';
import { translate } from 'react-i18next';
class TranslatableView extends Component {
foo() {
}
render() {
const { t } = this.props;
return (
<div>
<h1>{t('keyFromDefault')}</h1>
</div>
)
}
}
export default translate(['defaultNamespace', 'anotherNamespace'], { withRef: true })(TranslatableView);
import React, { Component } from 'react';
import ./TranslatableView;
class App extends Component {
handleClick() {
this.refs.translatedView.foo();
}
render() {
return (
<div>
<TranslatableView ref="translatedView" />
<button onClick={() => this.handleClick()}>Click</button>
</div>
)
}
}
Interpolate Component
Interpolate: component that allows to interpolate React Components or other props into translations.
- used nested inside I18nextProvider and translation hoc (context.i18n, context.t)
props:
- i18nKey: the key to lookup
- options: options to use for translation (exclude interpolation variables!)
- parent: optional component to wrap translation into (default 'span')
- useDangerouslySetInnerHTML: allows use of raw html tags in translation values
- dangerouslySetInnerHTMLPartElement: optional component to wrap parts of translation values into (default 'span'), used with
useDangerouslySetInnerHTML={true}
only - ...props: values to interpolate into found translation (eg.
my value with {{replaceMe}} interpolation
)
{
"interpolateSample": "you <strong>can</strong> interpolate {{value}} or {{component}} via interpolate component!"
}
import React from 'react';
import { translate, Interpolate } from 'react-i18next';
function TranslatableView(props) {
const { t } = props;
let interpolateComponent = <strong>a interpolated component</strong>;
return (
<div>
<Interpolate i18nKey='ns:interpolateSample' value='"some string"' component={interpolateComponent} />
{/*
=>
<span>
you <strong>can</strong> interpolate "some string" or <strong>a interpolated component</strong> via interpolate component!
</span>
*/}
<Interpolate i18nKey='ns:interpolateSample' useDangerouslySetInnerHTML={true} value='"some string"' component={interpolateComponent} />
{/*
=>
<span>
you <strong>can</strong> interpolate "some string" or <strong>a interpolated component</strong> via interpolate component!
</span>
*/}
</div>
)
}
Universal Rendering
loadNamespaces: Function that will pre-load all namespaces used by your components. Works well with react-router
match
function
props:
- components: Components that need to have namespaces loaded.
- i18n: the i18n instance to load translations into
import { I18nextProvider, loadNamespaces } from 'react-i18next';
import { match } from 'react-router';
match({...matchArguments}, (error, redirectLocation, renderProps) => {
loadNamespaces({ ...renderProps, i18n: i18nInstance })
.then(()=>{
})
});
When using i18next-express-middleware, you can use req.i18n
as the i18next
instance for I18nextProvider
:
import { I18nextProvider } from 'react-i18next';
import i18n from './i18next';
import App from './app';
app.use((req, res) => {
const component = (
<I18nextProvider i18n={req.i18n}>
<App />
</I18nextProvider>
);
});
Full sample/boilerplate for universal rendering.