DEV Community

Cover image for i18n of React with Lingui.js #1
stereobooster
stereobooster

Posted on

i18n of React with Lingui.js #1

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.

Top comments (12)

Collapse
 
siiidzej profile image
Václav Nosek

Hi
Thanks for simple yet powerful tutorial!

I have one question about how it works;
If you define default value (for default locale - en here) why would you also add-locale for the same language you define in Trans component?

Collapse
 
stereobooster profile image
stereobooster • Edited

I didn't understand your question. Can you provide code example, because it seems you use different terminology

Collapse
 
siiidzej profile image
Václav Nosek

I am trying your example code (github.com/stereobooster/react-lin...).

The point is; If I run npm run extract the language which is default(en) has all messages "Missing" (because it is non-sense to give translation to these as well if that is the source-of-truth).

Thread Thread
 
stereobooster profile image
stereobooster

Yes they missing, because there is no"sourceLocale": "en", otherwise they would be there. What is your question?

Thread Thread
 
siiidzej profile image
Václav Nosek • Edited

Catalog statistics is used to determine whether there are some non-translated messages therefore if You use it for any kind of automation (as a test) it wouldn't pass unless you translate the source messages as well.

I am asking if according to your opinion is this good practice or I am missing some point where you simply set "sourceLocale": "en" and problem solves? (because this isn't included in your, nor official example)

Thread Thread
 
stereobooster profile image
stereobooster

No "sourceLocale": "en" is not a solution. You can ask author for this feature

Collapse
 
dance2die profile image
Sung M. Kim

Thank you for the article there @sterobooster.

May I request if you can add links to (possibly in ToC format) next articles?

Collapse
 
stereobooster profile image
stereobooster

By any chance anyone knows how to place those dots navigation for series. I saw it in some posts, but have no idea how to do it

Collapse
 
dance2die profile image
Sung M. Kim

I've been manually entering Markdown ToC's as shown below.

# Table of Contents
1. [Example](#example)
2. [Example2](#example2)
3. [Third Example](#third-example)

## Example
## Example2
## Third Example

But not sure what you mean by dots navigation.

@andy & @ben
Is there a way to add dots navigation that @stereobooster is referring to by chance?

I was reading help document & liquid tags, but not sure if there is a standard way to add ToCs in dev.to

Thread Thread
 
andy profile image
Andy Zhao (he/him)

Think we're talking about two separate things.

I believe the dots navigation is making the post part of a series. If you're using the v1 editor, you can add a post to a series by adding a series: series name line in the front matter:
v1 editor example

If you're using the v2 editor, you can click the additional settings button next to the "IMAGES" button, and add the series from there.
v2 editor example part 1
v2 editor example part 2

For Table of Contents, we don't have anything that fully supports it yet but we have a PR that will make it a bit easier at least.

Thread Thread
 
stereobooster profile image
stereobooster

Thank you!! This is exactly what I was talking about

Thread Thread
 
dance2die profile image
Sung M. Kim

Thank you Andy 😀