How to integrate i18next Internationalization with your React project?
Tags: react, webdev, javascript, programming
Published: 2021-06-23 21:31:36

When are working on several projects and countries the language is one of the most important facts that we need to keep in mind, especially if our application was developed with the goal of having an international market. 

In some cases handle the internationalization in the projects is difficult and complicated, there are different tools that can be used with different approaches. For that reason with the post, I will explain to you about the **react-i18next** framework is a useful tool that can help us to integrate internationalization to our **React** project in a quick and awesome way.  


## i18next

> I18next is an internationalization framework written in and for JavaScript. But it's much more than that. I18next goes beyond just providing the standard i18n features such as (plurals, context, interpolation, format). It provides you with a complete solution to localize your product from web to mobile and desktop.

As you can see i18next is a framework that will help us to apply internationalization features to our Javascript projects.

## react-i18next

> react-i18next is a powerful internationalization framework for React / React Native which is based on i18next. The module provides multiple components eg. to assert that needed translations get loaded or that your content gets rendered when the language changes.

react-i18next is the best option when you want to add internationalization to your React project.

## Let's do it

### Create React project
First of all, we need to create a React project with the next command

```
npx create-react-app react-i18next-example
```

### Install dependencies
After that, we need to install the project dependencies 
```
npm install react-i18next i18next --save
```

As you can see we have installed also **i18next** when we will use **react-i18next** the reason is that **i18next** is the core that provides all translation functionality while **react-i18next** gives some extra power for proper use in React

### Configure

#### i18n.js

We need to create a new file **i18n.js** beside our index.js containing the following content

```js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";

const resources = {
  en: {
    translation: {
      "Welcome to React": "Welcome to React and react-i18next"
    }
  },
  fr: {
    translation: {
      "Welcome to React": "Bienvenue à React et react-i18next"
    }
  }
};

i18n
  .use(initReactI18next)
  .init({
    resources,
    lng: "en", 
    interpolation: {
      escapeValue: false
    }
  });

  export default i18n;
```

The interesting part here is by `i18n.use(initReactI18next)` we pass the i18n instance to **react-i18next** which will make it available for all the components via the context API.

After that, we need to import the **i18n.js** file into our index.js file


```js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import './i18n';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById("root")
);
```
When we that done the previous steps we can start to use **react-i18next**, for example, we can use the useTranslation hook.
#### App.js

```js
import "./styles.css";
import { useTranslation } from "react-i18next";

export default function App() {
  const { t } = useTranslation();
  return (
    <div className="App">
      <h1>{t("Welcome to React")}</h1>
    </div>
  );
}
```

After that, you will the next page based on the location language English or French

<iframe src="https://codesandbox.io/embed/react-i18next-example-02p18?autoresize=1&fontsize=14&hidenavigation=1&theme=dark&view=preview"
     style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
     title="react-i18next-example"
     allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
     sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
   ></iframe>

## Translate your content with different options
**react-i18next** offers some different options when we need to use internationalization in our project, some of them are

### Using useTranslation hook

Using the hook in functional components is one of the options you got. The **t** function is the main function in **i18next** to translate content.

```js
import React from 'react';

import { useTranslation } from 'react-i18next';

const MyComponent = () => {
  const { t } = useTranslation();
  return <h1>{t('Welcome to React')}</h1>
}
```

Learn more about the hook [useTranslation](https://react.i18next.com/latest/usetranslation-hook)

### Using withTranslation HOC
Using higher order components is one of the most used methods to extend existing components by passing additional props to them.

```js
import React from 'react';

import { withTranslation } from 'react-i18next';

const MyComponent = ({ t }) => {
  return <h1>{t('Welcome to React')}</h1>
}

export default withTranslation()(MyComponent);
```
Learn more about the higher order component [withTranslation](https://react.i18next.com/latest/withtranslation-hoc).

### Using the render prop
The render prop enables you to use the t function inside your component.

```js
import React from 'react';
import { Translation } from 'react-i18next';
const MyComponent = () => {
  return (
    <Translation>
      {
        t => <h1>{t('Welcome to React')}</h1>
      }
    </Translation>
  )
}
export default MyComponent;
```

Learn more about the render prop [Translation](https://react.i18next.com/latest/translation-render-prop).

### Using the Trans component

The Trans component is the best way to translate a JSX tree into one translation. This enables you to eg. easily translate text containing a link component or formatting like `<strong>`.

```js
import React from 'react';
import { Trans } from 'react-i18next';

const MyComponent = () => {
  return <Trans><H1>Welcome to React</H1></Trans>
}

export default MyComponent;
```
#### Note

The translation key and content, in this case, should be declared with the tags as the next example.

```json
"<0>Welcome to React</0>": "<0>Welcome to React and react-i18next</0>"
```

## Interpolation

Interpolation is one of the most used functionalities in I18N. It allows the integration of dynamic values into your translations. Per default, interpolation values get escaped to mitigate XSS attacks.

### Example 

With **i18next** we can pass params to our translations that will be integrated with the final translation render to do that we need to add the keys are strings surrounded by curly brackets:

```json
{
    "key": "{{what}} is {{how}}"
}
```
So when we call that translation we can pass the params to the **t** function

```
import "./styles.css";
import { useTranslation } from "react-i18next";

export default function App() {
  const { t } = useTranslation();
  return (
    <div className="App">
      <h1>{t("key", { what: "interpolation", how: "great" })}</h1>
    </div>
  );
}
```
You can see the example more detailed here

[![Edit react-i18next-example-interpolation](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-i18next-example-interpolation-jee12?autoresize=1&fontsize=14&hidenavigation=1&moduleview=1&theme=dark)

## Working with data models
Another awesome thing that can be used with interpolation is pass data models, we need to declare the translation key in a next way

```json
{
    "key": "I am {{author.name}}"
}
```
In the case of the React Component you just need to pass the `author` data to the interpolation.

```js
import "./styles.css";
import { useTranslation } from "react-i18next";

export default function App() {
  const { t } = useTranslation();
  const author = { 
    name: 'Brayan',
    github: 'Arrieta'
};
  return (
    <div className="App">
      <h1>{t("key", { author })}</h1>
    </div>
  );
}
```

## Conclusion

As you see **react-i18next** and **i18next** provides some awesome features that can be used in our projects in the case that our application wants to have an international market.

I hope you find this article really helpful to use internationalization in your **React** projects. I will be updating this post based on your comments and recommendations so let me know in any case. Thanks! 👍

<a href="https://www.buymeacoffee.com/brayanarrieta"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=brayanarrieta&button_colour=5F7FFF&font_colour=ffffff&font_family=Cookie&outline_colour=000000&coffee_colour=FFDD00"></a>

## References
- [react-i18next](https://react.i18next.com)
- [i18next](https://www.i18next.com/)