Translating React apps with i18next and testing them End-to-End with Playwright

JavaScript React

As a business grows, there is a high chance that it will expand to multiple different countries. The developers must ensure the application is available in different languages to accommodate that. Fortunately, we don’t have to create a separate version of our application in each language. Instead, we can use tools that let us dynamically load and display content that aligns with the user’s language.

In this article, we learn how to support multiple languages in a React application and write End-to-End tests using the Playwright library to ensure it works as expected.

Introducing the react-i18next library

Let’s start by creating a very simple component that we will be able to translate later.

Greeting.tsx

We can use the i18next library to display our component in multiple languages.

18 stands for the number of letters between the first i and the last n in the word internationalization and it is a common abbervation.

Configuring the i18next library

Let’s start by installing the necessary dependencies.

Now, we need to create a file that configures the i18next library.

i18next.tsx

Above, we provide translations for every language we want to support. We also set up the i18next library to use react-i18next so that we can use the translations with React Hooks.

It makes sense to move the translations into a separate file, or even fetch them from a server.

We also set to to indicate that we don’t want the i18next library to encode the translation values to prevent the XSS attacks. The React library already handles that.

The last step is to import our configuration file.

main.tsx

Translating the component

The most straightforward way of translating our component is to use React Hooks.

Greeting.tsx

When we call the function, the i18next library chooses the appropriate translation we’ve set up in the configuration.

Switching the language manually

In our configuration, we set the default language to English through . We can let the users switch the language by using the function.

LanguageSwitch.tsx

As soon as the user clicks on one of the buttons, the language of the whole application changes.

Detecting the language automatically

Instead of using English by default, we can use various language detection strategies. To do that, we can use the library.

To set it up, we need to adjust our i18next configuration slightly.

i18next.tsx

Above, we import and use the . We also provide an array of supported languages instead of setting a single language.

By default, the detects the language from multiple places in the following order:

  1. the query string
    – for example, by opening , we switch the language to Polish
  2. the cookie
    – if there is a cookie called that holds the language, the detector will use it
  3. the localStorage
    – if there is a value with the key in the local storage, the detector will use it
  4. the sessionStorage
    – if there is a value with the key in the session storage, the detector will set it as the current language
  5. the navigator
    – the browser sends various data to the server when requesting the website. One of them is the request header, which contains the language set in the browser’s configuration.
  6. the HTML tag
    – we can set the language through the attribute of the tag

If you want to change the suggested language for the websites you’re visiting using Chrome, go to

Thanks to this order, we can override any language setting if we send the query parameter. What’s important is that if the user sets the language, the library stores their choice in the local storage. Thanks to that, we can override the language configuration set in the browser.

You can pass additional options to configure how the language is detected.

Using interpolation

Sometimes, we need to concatenate multiple strings, and some of them can only be known at runtime. For example, let’s display the current day of the week.

CurrentDayOfTheWeek.tsx

Fortunately, the i18next library supports interpolation, allowing us to integrate dynamic values into our translations.

i18next.tsx

Now, our translation accepts a variable called . We can provide it when calling the function.

Similarly, the i18next library can handle singular and plural versions of translations and the context.

CurrentDayOfTheWeek.tsx

Above, we used the property to get the day of the week in the correct language from the function.

Writing End-to-End tests with Playwright

To test whether we display the day of the week correctly using Playwright, we must mock the current date. The most straightforward way is to inject a script into the tested website that mocks the constructor.

CurrentDayOfTheWeek.test.ts

Above, we use to navigate to our website. It works as expected because we configured the property using environment variables. If you want to know more, check out JavaScript testing #17. Introduction to End-to-End testing with Playwright

Now, let’s create two different test scenarios, one for each language. Fortunately, Playwright provides an easy way to set the locale per test block with the function. Since this affects the navigator, this approach ensures that our website correctly detects the language set in the browser.

CurrentDayOfTheWeek.test.ts

Summary

In this article, we’ve learned how to internationalize and translate our React application into different languages. We also implemented automatic language detection based on various factors. Besides that, we ensured that our application worked as expected by writing End-to-End tests using Playwright. To do that, we had to learn how to mock the current date and change the language settings in the browser where the End-to-End tests run.

Thanks to this approach, our application is now prepared for international users while ensuring it is reliable through testing.

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
gleb
6 months ago

Do you have a repo with the source code and the tests by any chance?