How to add namespaces in React i18next

Is your translation file getting to big for your React project?

Do you need a way to split your translation JSON file into multiple smaller files?

Let me show you how to accomplish that with react-i18next NPM module.

Setup translation files

In this example, I’m going to create 2 json files


{
  "greet": "Hi there, it's Ruben here!"
}

{
  "greet": "Hi there, I like cats! How about yourself?"
}

Setup i18n configuration file


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

import commonTranslationEN from "../public/locales/en/common.json";
import moduleATranslationEN from "../public/locales/en/moduleA.json";

const resources = {
  en: {
    // Namspaces
    common: commonTranslationEN,
    moduleA: moduleATranslationEN
  }
};

i18n

  // passes i18n down to react-i18next
  .use(initReactI18next)
  .init({
    resources,

    // Set default namespace
    defaultNS: "common",

    lng: "en",

    interpolation: {
      // react already safes from xss
      escapeValue: false
    }
  });

export default i18n;

Let’s do a breakdown of what’s happening here.

First I’m importing a couple i18n libraries, and I’m also importing the translation files.


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

import commonTranslationEN from "../public/locales/en/common.json";
import moduleATranslationEN from "../public/locales/en/moduleA.json";

Pretty easy stuff!

Setup React i18n resources

The next step I’m taking is to create an object that maps my translations files to the desired namespace.


const resources = {
  en: {
    // Namspaces
    common: commonTranslationEN,
    moduleA: moduleATranslationEN
  }
};

In my en property, I’m creating common, and moduleA as namespaces.

And I’m attaching a translation JSON object to them.

Choose default namespace

In the i18n.init() function, I’m passing the resources map, and I’m setting a default namespace.


i18n

  .init({

    resources,

    // Set default namespace
    defaultNS: "common",

    // other configs...
  });

Now that the configuration has been completed, I’m going to create a React component to utilize react-i18next with it’s namespaces.

Use props.t() function in React component


import * as React from "react";
import { render } from "react-dom";
import "./i18n";
import { withTranslation } from "react-i18next";

const App = withTranslation()(props => {
  const [showCatGreetMssg, setShowCatGreetMssg] = React.useState(false);

  const handleClick = () => setShowCatGreetMssg(true);

  return (
    <>
      <h1>
        {!showCatGreetMssg ? props.t("greet") : props.t("moduleA:greet")}
      </h1>
      <button onClick={handleClick}>Change message</button>
    </>
  );
});

render(<App />, document.getElementById("root"));

React code breakdown!

Before I begin calling my greet messages, I have to import a few files first.


import "./i18n";
import { withTranslation } from "react-i18next";

In the code example above, I’m importing my i18n configuration file.

I’m also importing one of react-i18next utility functions, withTranslation.


withTranslation()(Component);

withTranslation is a HOC (higher order component) function type.

When you use the withTranslation utility function, withTranslation will pass the translate function via React props, props.t().


<h1>
  {!showCatGreetMssg ? props.t("greet") : props.t("moduleA:greet")}
</h1>

In the code snippet above you’ll the code utilize the translate function, and passing a string value in 2 different formats.


// Uses default namespace common
props.t("greet") // Hi there, it's Ruben here!

// Calling namespace "<namespace_identifier>:<message_identifier>"
props.t("moduleA:greet") // Hi there, I like cats! How about yourself?

If I didn’t set a default namespace in my i18n file the first props.t() call would have not work.

I would have to use it as such:


props.t("common:greet")

Conclusion

Creating namespaces for your i18n locales will help alleviate the pain of having a large translation file.

react-i18next makes it easy to setup namespaces and to call them into your React application.

I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!