Skip to content

Internationalization for react done right. Using the i18next i18n ecosystem.

License

Notifications You must be signed in to change notification settings

wenom64/react-i18next

 
 

Repository files navigation

react-i18next

Higher-order components and components for React when using i18next.

NPM

Travis CI Coverage Status Quality dependencies devdependencies

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'; // your entry page
import i18n from './i18n'; // initialized i18next instance

ReactDOM.render(
  <I18nextProvider i18n={ i18n }><App /></I18nextProvider>,
  document.getElementById('app')
);

You can safely set escapeValue to false in interpolation options as react take care of escaping, see the sample.

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) or by passing i18n as a prop
  • 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

options:

{
  withRef: false,         // store a ref to the wrapped component
  translateFuncName: 't', // will change the name of translation prop default 't'
  wait: false,            // delay rendering until translations are loaded - wait can be set globally on i18next init too
  bindI18n: 'languageChanged loaded',   // which events trigger a rerender, can be set to false or string of events
  bindStore: 'added removed'            // which events on store trigger a rerender, can be set to false or string of events
}
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 per options in hoc or globally on i18next.init 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() {
    // do something important
  }

  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 &lt;strong&gt;can&lt;/strong&gt; 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>
  )
}

You can use formatting, see the sample.

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(()=>{
      // All i18n namespaces required to render this route are loaded   
   })
});

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'; // your own initialized i18next instance
import App from './app';

app.use((req, res) => {
   const component = (
      <I18nextProvider i18n={req.i18n}>
         <App />
      </I18nextProvider>
   );

   // render as desired now ...
});

Full sample/boilerplate for universal rendering.

Typescript users

For Typescript users, if you are running into issues, such as Uncaught TypeError: Cannot read property 'off' of undefined, it's possible that you have not exported your own initialized i18next instance correctly. Try the following:

import * as i18n from 'i18next'
import * as XHR from 'i18next-xhr-backend'
import * as LanguageDetector from 'i18next-browser-languagedetector'
import config from '../src/config/config'

const instance = i18n
  .use(/* your settings */)
  .init({
    // your settings here
  })

export default instance

About

Internationalization for react done right. Using the i18next i18n ecosystem.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%