React and i18n - translate by adding the locale in the URL React and i18n - translate by adding the locale in the URL reactjs reactjs

React and i18n - translate by adding the locale in the URL


I needed the same thing and I found out that you can set the whitelistproperty of i18n.init options and specify the supported languages. After that, if you set checkWhitelist: true inside your detection options, the LanguageDetector will only match the language if it exists on the whitelist array.

Anyway, you still need to define the languageChanged event in order to redirect the page when matching the default language but, you no longer need to redirect if it is another supported language (at least I don't need).

Last thing that I did differently is that I defined the languageChanged event first and only then called the i18n.init, so that it would trigger the event already for the first time that it sets the language.

Here's my code:

i18n.js

import i18n from 'i18next'import LanguageDetector from 'i18next-browser-languagedetector'i18n.on('languageChanged', function (lng) {  // if the language we switched to is the default language we need to remove the /en from URL  if (lng === i18n.options.fallbackLng[0]) {    if (window.location.pathname.includes('/' + i18n.options.fallbackLng[0])) {      const newUrl = window.location.pathname.replace('/' + i18n.options.fallbackLng[0], '')      window.location.replace(newUrl)    }  }})i18n  .use(LanguageDetector)  .init({    resources: {      en: {        translation: require('./translations/en.js').default      },      pt: {        translation: require('./translations/pt.js').default      }    },    whitelist: ['en', 'pt'],    fallbackLng: ['en'],    detection: {      order: ['path'],      lookupFromPathIndex: 0,      checkWhitelist: true    },    interpolation: {      escapeValue: false,      formatSeparator: '.'    }  })export default i18n

App.js

import { Route, Switch } from "react-router-dom";import AboutPage from "./AboutPage";import HomePage from "./Homepage/HomePage";import NotFoundPage from "./NotFoundPage";import PropTypes from "prop-types";import React from "react";import { hot } from "react-hot-loader";import {  Collapse,  Navbar,  NavbarToggler,  NavbarBrand,  Nav,  NavItem,  NavLink } from 'reactstrap';import i18n from "../i18n";const baseRouteUrl = "/:locale(pt|en)?";export const baseUrl = i18n.language === 'en' ? '' : '/'+i18n.language;class App extends React.Component {  state = {    isOpen: false  }  render() {    return (      <div>        <div>          <Navbar color="grey" expand="md">            <NavbarBrand href="/">Testing</NavbarBrand>            <Nav className="ml-auto" navbar>              <NavItem>                <NavLink href={baseUrl + "/"}>Home</NavLink>              </NavItem>              <NavItem>                <NavLink href={baseUrl + "/about/"}>About</NavLink>              </NavItem>            </Nav>          </Navbar>        </div>        <Switch>          <Route exact path={baseRouteUrl + "/"} component={HomePage} />          <Route path={baseRouteUrl + "/about"} component={AboutPage} />          <Route component={NotFoundPage} />        </Switch>      </div>    );  }}App.propTypes = {  children: PropTypes.element};export default hot(module)(App);

In my case, when I need to translate something, I import my i18n.js and call the respective key like this:

<div>{i18n.t('home.bannerStart')}</div>