Setup localization

We suggest configuring i18n even if you're not going to need multiple languages -- as long as you have at least one natural language in your app.

It's often much easier -- and hardly any extra work -- to do it at this point than later.

Install dependencies

Install the i18n package:

npm i --save-dev react-i18next i18next

Create translation files

Create src/languages directory with src/languages/en.js:

{
  "page.title": "Hello world"
}

...and src/languages/fi.js (if you need another language, use standard language codes):

{
  "page.title": "fi-Hello world"
}

This way you can easily test the translation even if you don't yet have correct translation tokens.

Notice also, that we use flat key-value format. This is intentional design choice. You could also use non-flat, but you would just make life harder for yourself later when you're converting files from 3rd party XML, etc. Keep things simple.

Finally, create an index file src/translations/index.ts:

import en from "./en.json";
import fi from "./fi.json";

export {
    en,
    fi
};

Create translation token file

Next, create src/constants/translation.ts with content:

export const T_PAGE_TITLE = "page.title";

This way it's easy to detect dead tokens and keep track of all translation tokens your app has.

Default language

Append to src/constants/frontend.ts:

export const FRONTEND_DEFAULT_LANGUAGE = 'en';

You could also configure this at src/constants/environment.ts so that it could be configured at build time.

Create i18n configuration file

Create file src/i18n.ts with content:

import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import { en, fi } from "./translations";
import { FRONTEND_DEFAULT_LANGUAGE } from "./constants/frontend";

const resources = {
    en: {translation: en},
    fi: {translation: fi}
};

i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
    resources,
    lng: FRONTEND_DEFAULT_LANGUAGE,
    interpolation: {
        escapeValue: false // react already safes from xss
    }
});

export default i18n;

Then, append import "./i18n"; to src/index.tsx.

Using translations

Here's how to use it:

import { useTranslation } from "react-i18next";
import { T_PAGE_TITLE } from "../constants/translation";
export function Foo () {
    const { t } = useTranslation();
    return (
        <div>
            <h1>{t(T_PAGE_TITLE)}</h1>
        </div>
    );
}

Notice, how easy it will be (with a modern IDE) to find any location where a specific translation token is used.

Especially you don't need to write complex and erroneous crawler scripts to figure that out.