How to translate location URL when changing language?
Asked Answered
P

1

8

I am currently facing a wall in the localization process of a website. Using i18next, all of our routes are translated and default language has the locale path removed from the URL.

In other words:
/accueil -> /en/home
/produits -> /en/products
and so on...

My issue is when I change the language, the url does not follow (which is to be expected, since i18next doesn't talk directly to react-router).

i18next configuration:

i18n
  .use(detector)
  .use(initReactI18next)
  .init({
    whitelist: ['fr', 'en'],
    fallbackLng: 'fr',
    defaultNS: 'common',

    detection: {
      lookupFromPathIndex: 0,
      checkWhitelist: true
    },

    interpolation: {
      escapeValue: false
    },

    resources: {
      en: {
        routes: enRoutes,
        [...]
      },
      fr: {
        routes: frRoutes,
        [...]
      }
    }
  });

fr/routes.json:

{
  "home": "/accueil",
  "products": "/produits",
  [...]
}

en/routes.json:

{
  "home": "/en/home",
  "products": "en/products",
  [...]
}

Router portion in app.jsx:

<Router forceRefresh>
  <Switch>
    <Route path={`/:locale(en|fr)?${t('routes:home')}`} component={HomeComponent} />
    <Route path={`/:locale(en|fr)?${t('routes:products')}`} component={ProductsComponent} />
  </Switch>
</Router>

With the following configuration, pages render without issue and easily translate when i18n.changeLanguage is called, but the url doesn't change with it. I've searched everywhere and can't seem to find a go-to approach to translate the url once the language is changed.

I also want to handle a case where the user would change the locale manually directly in the browser url field.

I have tried updating the url on 'languageChanged' event in i18next, but finding the key to the page currently being since adds a lot of complications.

Thx in advance for any help provided.

Perverted answered 1/9, 2020 at 0:40 Comment(6)
What about your Link tags? Their paths need to change too? Are you making sure they are changing as well?Nola
yes they change too, my issue really falls on the moment i18n.changeLanguage() is called. I'm thinking of resorting to a custom change language function, dynamically finding the key to the route before triggering the language change, then redirecting with said key.Perverted
Couldn't something like this suffice? We did build an app that had internationalization without any library with our own custom hook. Anyways, what benefits does it provides anyways?Nola
Localized url is important for SEO, the translation isn't the issue, the localization of the URLs is.Perverted
Is this what you're after?Nola
That is indeed the end result. I am looking for. I currently have all of that. The only thing missing is for the url to be correctly set once the language changes.Perverted
P
3

I finally found an easy and clean method to change the route while also changing the language.

  const changeLanguage = (nextLanguage) => {
    const routes = i18n.getResourceBundle(i18n.language, 'routes');
    const currentPathname = window.location.pathname.replace(/\/+$/, '');
    const currentRouteKey = Object.keys(routes).find((key) => routes[key] === currentPathname);

    window.location.replace(t(`routes:${currentRouteKey}`, { lng: nextLanguage }));
  };

I also needed to change the i18next detection options as follow:

detection: {
  order: ['path', ...otherMethods]
  lookupFromPathIndex: 0,
  checkWhitelist: true
},

I can now safely call this changeLanguage wrapper anywhere and it will handle both the language change (which goes to the default in case it's not part of the url) and the route change.

Perverted answered 1/9, 2020 at 5:44 Comment(1)
Hi fellow pogrammer. I just stumbled upon this, its only 20 days old. So while the iron is hot. let me ask you for a gist to explain further, what and how you did? Would upvote ;-)Alliterative

© 2022 - 2024 — McMap. All rights reserved.