Categories
React

react-i18next NPM Package — withTranslation

Spread the love

If we want to add localization to a React app, we can use the react-i18next NPM package to do it.

In this article, we’ll look at how to load translations with the withTranslation higher-order component.

withTranslation

The withTranslation higher-order component lets us wrap our component to let us gain access to the t function and i18n object.

For example, we can write:

import React from "react";
import i18n from "i18next";
import { initReactI18next, withTranslation } from "react-i18next";

const resources = {
  en: {
    ns1: {
      "Welcome to React": "Welcome to React and react-i18next"
    }
  }
};

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

function App({ t }) {
  return (
    <div className="App">
      <p>{t("Welcome to React")}</p>
    </div>
  );
}

export default withTranslation("ns1")(App);

We called the withTranslation higher-order component with the namespace to load the ns1 translation namespace.

Also, we can load multiple namespaces with it.

For example, we can write:

import React from "react";
import i18n from "i18next";
import { initReactI18next, withTranslation } from "react-i18next";

const resources = {
  en: {
    ns1: {
      "Welcome to React": "Welcome to React and react-i18next"
    },
    ns2: {
      Hello: "Hello World"
    }
  }
};

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

function App({ t }) {
  return (
    <div className="App">
      <p>{t("Welcome to React")}</p>
      <p>{t("ns2:Hello")}</p>
    </div>
  );
}

export default withTranslation(["ns1", "ns2"])(App);

to load the ns1 and ns2 namespaces.

Any namespace after the first needs the namespace name.

Overriding the i18next Instance

We can override the i18next instance, by passing an object to the i18n prop:

import React from "react";
import i18n from "i18next";
import { initReactI18next, withTranslation } from "react-i18next";

const resources = {
  en: {
    ns1: {
      "Welcome to React": "Welcome to React and react-i18next"
    },
    ns2: {
      Hello: "Hello World"
    }
  }
};

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

const MyComponent = ({ t }) => {
  return (
    <div className="App">
      <p>{t("Welcome to React")}</p>
    </div>
  );
};

const ExtendedComponent = withTranslation("ns1")(MyComponent);

export default function App() {
  return (
    <div className="App">
      <ExtendedComponent i18n={i18n} />;
    </div>
  );
}

We pass it into the ExtendedComponent which is created from the withTranslation component.

Also, we can disable the use of the Suspense component with the useSuspense prop.

For example, we can write:

import React from "react";
import i18n from "i18next";
import { initReactI18next, withTranslation } from "react-i18next";

const resources = {
  en: {
    translation: {
      "Welcome to React": "Welcome to React and react-i18next"
    }
  }
};

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

const MyComponent = ({ t, tReady }) => {
  return (
    <div className="App">
      <p>{tReady && t("Welcome to React")}</p>
    </div>
  );
};

const ExtendedComponent = withTranslation()(MyComponent);

export default function App() {
  return (
    <div className="App">
      <ExtendedComponent useSuspense={false} />
    </div>
  );
}

If we set useSuspense to false , then we have to use the tReady prop to check if the translation is ready.

Conclusion

The react-i18next NPM package has the withTranslation higher-order component to provide the required translations functions and objects via the props.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *