Search code examples
reactjsbabeljsi18nextreact-i18next

react-i18next with multiple translation-files


I have a little problem in my application. I use i18next and react-i18next for the translation and have already included it. The whole translation comes from 1 file for each language and that is a mess with over 4000 rows :(

Now I want update this so that i18next would take the translation files placed in the different component-folders and their children-folders.

The folder-structure should look like this after the update:

scr
- components
-- Header
---translations (en/translation.json, de/translation.json)
-- Dashboard
--- translations (en/translation.json, de/translation.json)
--- Menu
---- translations (en/translation.json, de/translation.json)
---- ExampleComponent.tsx
---- ...
--- Cards
---- translations (en/translation.json, de/translation.json)
...

I already figured out how I can handle the automatic export via babel and babel-i18next-plugin with the "namespace"

So, my code (example Menu) would be written like this:

const { t } = useTranslation("Dashboard/Menu")

const explString = t("ExampleComponent.ExampleString","This is an example")

In babel I placed the plugin like this:

[i18next-plugin, {"outputPath": "src/components/{{ns}}/translations/{{locale}}/translation.json"}]

This runs without problems. It takes the namespace as a folder-structure and places the translation-files into the translation-folder including the correct keys.

Now, how I can tell i18next, where to find the translation-files? I could only figure out that I can import the files (file-by-file) inside a resource. I tried backend plugins (html-backend, async-storage-backend, local-storage-backend and filesystem) with

backend: { loadPath: "components/{{ns}}/translations/{{lng}}/translation.json" }

(The i18next.ts is placed inside src/)

and I get the warnings that the keys aren't found.

Also, you can see that I use TypeScript.

In my webpack I tried it with the ts-i18next-loader with this inside the webpack configuration file:

  {
    test: /\translation.json$/,
    exclude: /node_modules/,
    loader: 'i18next-ts-loader',
    options: {
      localeFilesPattern: 'src/components/{{ns}}/translations/{{lng}}/translation.json',
    },
  },

If I only had 5-6 translation-files for each language / namespace it would not be a problem to put it inside the resource but at the end I have more than 100 files for each language.

Would be nice if anyone had a solution to my problem. If you need any further information I can update the post.

Cheers


Solution

  • There's an alternative plugin to be used, suggested in the official documentation: https://www.i18next.com/how-to/add-or-load-translations#lazy-load-in-memory-translations

    i18next-resources-to-backend helps to transform resources to an i18next backend. This means, you can also lazy load translations, for example when using webpack:

    import i18next from 'i18next';
    import resourcesToBackend from 'i18next-resources-to-backend';
    
    i18next
      .use(resourcesToBackend((language, namespace, callback) => {
        import(`./locales/${language}/${namespace}.json`)
          .then((resources) => {
            callback(null, resources)
          })
          .catch((error) => {
            callback(error, null)
          })
      }))
      .init({ /* other options */ })