Internationalization of React Apps

Now we need to integrate LinguiJS to React App.

Create I18nLoader

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { I18nProvider } from '@lingui/react';

const propTypes = {
  language: PropTypes.string,
  children: PropTypes.node,
};

const defaultProps = {
  language: 'en',
  children: null,
};

class I18nLoader extends React.Component {
  state = {
    catalogs: {},
  };

  componentDidMount() {
    const { language } = this.props;
    this.loadCatalog(language);
  }

  shouldComponentUpdate(nextProps, nextState) {
    const { language } = nextProps;
    const { catalogs } = nextState;
    const { language: currentLanguage } = this.props;

    if (language !== currentLanguage && !catalogs[language]) {
      this.loadCatalog(language);
      return false;
    }

    return true;
  }

  loadCatalog = async language => {
    const catalog = await import(/* webpackMode: "lazy", webpackChunkName: "i18n-[index]" */
    `@lingui/loader!locales/${language}/messages.json`);
    this.setState(state => ({
      catalogs: {
        ...state.catalogs,
        [language]: catalog,
      },
    }));
  };

  render() {
    const { children, language } = this.props;
    const { catalogs } = this.state;

    // Skip rendering when catalog isn't loaded.
    if (!catalogs[language]) return null;

    return (
      <I18nProvider language={language} catalogs={catalogs}>
        {children}
      </I18nProvider>
    );
  }
}

const getLanguage = state => state.locale.language;

I18nLoader.propTypes = propTypes;
I18nLoader.defaultProps = defaultProps;

export default connect(state => ({
  language: getLanguage(state),
}))(I18nLoader);

Connect with the redux store and fetching locale data from the redux state.

I am storing the user-selected store in redux store you can store it in cookies, localstorage, or using context or state in your app.

Wrap app with I18nLoader

import React from 'react';
import I18nLoader from './I18nLoader';
import App from './App'

render(
  <I18nLoader>
    <App />
  </I18nLoader>,
  document.getElementById('app-root')
);

Now we are going to prepare our app content for translation

Wherever we need to make the text translatable, we just need to wrap it in <Trans> macro.

import { Trans } from '@lingui/macro';

<h1><Trans>Message Inbox</Trans></h1>

After wrapping text with Trans macro, we want to maintain keys for the text we want to translate in order to that we need to run extract command.

Once you will run extract command it will add all the text wrapped with <Trans> as key in all the locale files. By default file with source language in .linguirc will have wrapped text as a value too, in our case it’s English.

Congratulations basic setup and integration of LinguiJS with ReactJS is ready.

5

Leave a Reply

Your email address will not be published. Required fields are marked *