React Localization with i18next and Google Translate
Tags: react, javascript, localization, i18next
Published: 2020-11-06 06:43:29

We’re going to take a look at localizing a React app with [react-i18next](https://github.com/i18next/react-i18next) and [i18nexus](https://i18nexus.com). i18next is one of the most popular JavaScript localization libraries around, but its power is truly unleashed when used with i18nexus and its awesome API for scalable translation management and Google Translate automation.

## Start up the project

I am going to bootstrap together a simple React application using [create-react-app](https://github.com/facebook/create-react-app):

`npx create-react-app my-app`

Next, let’s `cd` into the React app directory and install a few i18next packages:

`npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector --save`

Don’t worry, these packages are all very lightweight and easy to use. Here’s what they do:

[i18next](https://github.com/i18next/i18next/): The base i18next library.
[react-i18next](https://github.com/i18next/react-i18next): Gives us React-friendly hooks, components, and functions for i18next.
[i18next-http-backend](https://github.com/i18next/i18next-http-backend): Let’s us use AJAX for loading translation files.
[i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector): Detects your users’ preferred language based on browser settings.

Let’s start up our development server with npm start

*Here we go!*

## i18next + i18nexus = 🔥

Ever since I started using [i18nexus](https://i18nexus.com), I haven’t used i18next without it. i18nexus allows us to store our app strings in the cloud and automatically translates them to as many languages as we want. Whenever you’re ready to hire professional translators, you simply invite them to the i18nexus project and you’re done.

In one word: AWESOME.

Go to [i18nexus.com](https://app.i18nexus.com/sign-up) and sign up for a free account. After naming your project you’ll be directed to your language dashboard:

![](https://cdn-images-1.medium.com/max/5760/1*zgr5uxRCnIgzGrr_niCAwA.png)

The first language tile is your base language — the language you’re *translating from*.

Click “Add Language” to select a language that you want your app to use. You can select as many as you want. I think I’ll select Spanish:

![Language Selection](https://cdn-images-1.medium.com/max/5760/1*Vg8xnjQZyDAsDpSjNpcFNw.png)

Next, let’s go to the page where we’ll be adding our strings. Click **Open Project** in the top right corner to be directed to the Strings Management page.

To add your first string, click **Add String**. I’m going to add a string that welcomes users to my app:

![**Key**: “welcome_msg” **Value**: “Hello, and welcome to my app!”](https://cdn-images-1.medium.com/max/5760/1*NQxJoouR4yNydqtOAi_kGA.png)

The **key** is how you’ll reference this string in your app.

The **value** is the text that will be displayed in your app.

The **details** field is optional. It is meant to provide any extra information about the context of your string for when you’re ready to bring in professional translators. You can even add an image here for more context!

After adding the string, you can expand the row to see the auto-translations:

![Strings automatically translated](https://cdn-images-1.medium.com/max/5760/1*O-1Bd-1p37uTseAW8w4OCQ.png)

## Let’s connect to our app

Back in the Export tab, we can find an i18next configuration code snippet to connect our React app to our i18nexus translations. Make sure to copy from the **React** tab:

![](https://cdn-images-1.medium.com/max/2656/1*-qGCwjH4BPfeJBq3qyjnOw.png)

Let’s create a file called i18n.js in our src folder, and then paste in the code snippet:

![](https://cdn-images-1.medium.com/max/4924/1*iAIY07wOJjBJzgZpapcSqA.png)

*Learn more about i18next configuration options [here](https://www.i18next.com/overview/configuration-options).

This code is asynchronously fetching our strings from the i18nexus API. I’ve never had problems with load speed, but for production environments it is recommended to use the i18nexus CDN and implement browser caching. We won’t go over that in this tutorial, but you can learn more about that [here](https://i18nexus.com/quick-integration/).

I’m going to import the i18n.js file in index.js, and then use React’s Suspense component to prevent rendering until the request is complete.

My index.js file now looks like this:

```
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "./i18n.js";

ReactDOM.render(
  <React.StrictMode>
    <Suspense fallback="loading">
      <App />
    </Suspense>
  </React.StrictMode>,
  document.getElementById("root")
);

serviceWorker.unregister();
```

## Rendering our strings

When the app loads, it is fetching all of our strings from i18nexus. Right now, my app just has the default create-react-app page with hardcoded strings:

![Default create react app screen](https://cdn-images-1.medium.com/max/5668/1*lV2cFW4MU6JdrfjSQcqcpg.png)

Let’s replace the text with our own strings!

## useTranslation

To use our strings, we have to import the `useTranslation` hook from react-i18next. This hook returns a function named `t` that we can use to get a string by passing the **key** as the first argument.

Back in i18nexus, the string I added has the key “welcome_msg”. Let’s render it. My App.js file now looks like this:

```
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { useTranslation } from "react-i18next";

function App() {
  const { t } = useTranslation();

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>{t("welcome_msg")}</p>
      </header>
    </div>
  );
}

export default App;
```

And here it is!

![The rendered English string](https://cdn-images-1.medium.com/max/5664/1*C7Erl17P-QfrpvVtEPj1qA.png)

Since my personal browser language is set to English, i18next has automatically chosen to render the English version of the string. This is thanks to the i18next-browser-languagedetector library!

To let the user choose their language, you would simply create a dropdown that calls `i18next.changeLanguage(<language_code>)` on change. Of course you can read more about all the i18next functions in the [i18next docs](https://www.i18next.com/).

For now, if you want to preview what your app would look like in another language, add the `lng` query parameter to the URL. If I load the app with [http://localhost:3000/?lng=es](http://localhost:3000/?lng=es), i18next will use the Spanish translations:

![[http://localhost:3000/?lng=es](http://localhost:3000/?lng=es)](https://cdn-images-1.medium.com/max/5760/1*CdZ_ctbQrYT-NSprNvnrkA.png)

AWESOME!

## Interpolation

Let’s add another string to i18nexus that uses **interpolation**. (Learn more about i18next interpolation [here](https://www.i18next.com/translation-function/interpolation))

In i18nexus, I’m going to create a string with the value “My name is `{{name}}`”. i18next uses double curly braces for interpolation:

![i18nexus even has syntax highlighting for interpolation](https://cdn-images-1.medium.com/max/4392/1*KzVpA4ZV5gfCbAlxJwOi1Q.png)

Now let’s use the `t` function with interpolation:

```
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { useTranslation } from "react-i18next";

function App() {
  const { t } = useTranslation();
  const userName = "David";

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>{t("welcome_msg")}</p>
        <p>{t("my_name", { name: userName })}</p>
      </header>
    </div>
  );
}

export default App;
```

And now we see the interpolated value:

![](https://cdn-images-1.medium.com/max/5760/1*CCtCayec2ufUCZcoCbK-YQ.png)

Your app has access to all strings and translations immediately after you add them to i18nexus. **I love it**.

Now I’m going to add German to my project in the i18nexus dashboard:

![Adding German to my project](https://cdn-images-1.medium.com/max/5472/1*brnIeJ5lQQCpwUMg8OWxiw.png)

When you add another language to your i18nexus project, remember to update the `supportedLngs` parameter in your i18n.js file by adding the new language code to the array.

Alternatively, you can copy/paste the code snippet from the Export tab again. I’m just going to manually add “de” to my `supportedLngs`:

```
i18next
  .use(HttpBackend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",

    ns: ["default"],
    defaultNS: "default",

    supportedLngs: ["en", "es", "de"],

    backend: {
      loadPath: loadPath
    }
  });
```

Now let’s visit http://localhost:3000/?lng=de to see our app in German:

![[http://localhost:3000/?lng=de](http://localhost:3000/?lng=de)](https://cdn-images-1.medium.com/max/5760/1*1GeqFy1ZCLtO0Kwkhn81Kg.png)

*Awesome!* (*Or should I say* “*das ist fantastisch!”)*

## To sum it up

**i18next** and **i18nexus** are an amazing duo for scalable localization in React. We have only scratched the surface with the customization available in both i18next and i18nexus, but hopefully this was enough to get you up and going! Feel free to ask any questions in the comments.