Supporting multiple languages in a PWA — Part Two — Using the i18next library

You can find the first part of this post here.

Adding internationalization

There are a couple of internationalization aka i18n libraries for React. I picked react-i18next. It is a wrapper around i18next that makes it usable in React. “i18next” has it has good documentation and is the most downloaded internationalization library for React on npm. You can install it with: npm install i18next react-i18next

Create a file called i18n.ts

Mine looks like:

In your index.tsx, add an import to make sure initialization happens before the app starts:

After initializing the react-i18next library, how do we use it?

In the App.tsx, add the following import:

In the render method, destructure “t” from the useTranslation and use it to replace the static texts in the links. Pass the keys from the i18n.ts file to the t() function to retrieve their respective translation:

In the Home.tsx, About.tsx and News.tsx you can do the same.

But, this breaks some tests…

If you run npm test you will notice the tests broke:

It cannot resolve the texts from the i18n library because we didn’t import the i18n.ts file in our test. To fix this, simply add the i18n.ts import to the App.test.tsx:

This should fix the tests again.

Adding another language

In the i18n.ts file add a Dutch translation:

For this example I didn’t buy a Dutch and English domain. Let’s pretend localhost is an English .com domain and 127.0.0.1 is the .nl (Dutch) domain. If the hostname is 127.0.0.1, load Dutch. For all other hostnames just load English. Here is how I implement this logic in i18n.ts:

If you run it with npm start and visit the url http://127.0.0.1:3000 to see if you app renders correctly in Dutch. Here you can see both versions:

Testing Dutch

I figure we want to automate testing whether the Dutch labels actually keep working when we change something (for example upgrading libraries). We should create at least one test that initializes the app in Dutch that verifies some text.

So how do we tell our test to load the app in Dutch? My first idea was to use the same hack we did in our English tests, but then point it to our “Dutch domain”, 127.0.0.1:

The problem here is that the import ‘./locales/i18n’; loads the bundle before this beforeEach happens, and then the i18n is already initialized with English.

Then I found is that the i18next library has a changeLanguage function. So import this “i8next” to the file and call the changeLanguage function in a beforeAll block:

Now all tests pass again!

Continue to part three

In the next part I’ll show how to add dynamic page titles and meta data. Or you can check out the source code directly on GitHub.

Java/TypeScript Developer. Interested in web/mobile/backend/database/cloud. Freelancing, only interested in job offers from employers directly. No middle men.