i18n of React with Lingui.js #1

stereobooster - Nov 18 '18 - - Dev Community

Everybody talking about React Hooks after React Conf. Other talks didn't get that much attention. It's a pity because there was absolutely brilliant talk about i18n/l10n of React applications - Let React speak your language by Tomáš Ehrlich.

In this post, I want to show how to use Lingui.js to do i18n/l10n of React applications. I will use Node 10.10 and yarn, but I guess npm and other versions of Node would work too. The full source code is here. Each step of the tutorial is done as a separate commit, so you can trace all changes of the code.

Install

Follow Create React App documentation for more info. Boostrap your project with following commands:

npx create-react-app react-lingui-example
cd react-lingui-example

Install @lingui/cli, @lingui/macro and Babel core packages as a development dependencies and @lingui/react as a runtime dependency.

npm install --save-dev @lingui/cli@next @lingui/macro@next @babel/core babel-core@bridge
npm install --save @lingui/react@next

# or using Yarn
yarn add --dev @lingui/cli@next @lingui/macro@next @babel/core babel-core@bridge
yarn add @lingui/react@next

Create .linguirc file with LinguiJS configuration in root of your project (next to package.json):

{
  "localeDir": "src/locales/",
  "srcPathDirs": ["src/"],
  "format": "lingui",
  "fallbackLocale": "en"
}

This configuration will extract messages from source files inside src directory and write them into message catalogs in src/locales.

Add following scripts to your package.json:

{
  "scripts": {
    "start": "lingui compile && react-scripts start",
    "build": "lingui compile && react-scripts build",
    "add-locale": "lingui add-locale",
    "extract": "lingui extract",
    "compile": "lingui compile"
  }
}

Run npm run add-locale (or yarn add-locale) with locale codes you would like to use in your app:

npm run add-locale en

# or using Yarn
yarn add-locale en

Check the installation by running npm run extract (or yarn extract):

npm run extract

# or using Yarn
yarn extract

There should be no error and you should see output similar following:

yarn extract
Catalog statistics:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ en       │      0      │    0    │
└──────────┴─────────────┴─────────┘

(use "lingui add-locale <language>" to add more locales)
(use "lingui extract" to update catalogs with new messages)
(use "lingui compile" to compile catalogs for production)

Congratulations! You’ve sucessfully set up project with LinguiJS.

Basic usage

(based on example project)

Create src/i18n.js:

import { setupI18n } from "@lingui/core";

export const locales = {
  en: "English",
  cs: "Česky"
};
export const defaultLocale = "en";

function loadCatalog(locale) {
  return import(/* webpackMode: "lazy", webpackChunkName: "i18n-[index]" */
  `./locales/${locale}/messages.js`);
}

export const i18n = setupI18n();
i18n.willActivate(loadCatalog);

Add src/locales/*/*.js to .gitignore.

Add <I18nProvider> to the App:

import { I18nProvider } from "@lingui/react";
import { i18n, defaultLocale } from "./i18n";

i18n.activate(defaultLocale);

class App extends Component {
  render() {
    return <I18nProvider i18n={i18n}>{/* ... */}</I18nProvider>;
  }
}

Use <Trans> macro to mark text for tanslation:

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

// ...

<Trans>Learn React</Trans>;

Run npm run extract (or yarn extract):

yarn extract
Catalog statistics:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ en       │      2      │    2    │
└──────────┴─────────────┴─────────┘

Now you can start your development environment with npm run start (or yarn start).

You can edit src/locales/*/messages.json to change translations or upload those files to translation service.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .