1

I have saved file in public folder in react for different language for translation. now I have requirement to get that data from API. I am able to call API and get data. I also know how to use translation. but I am not able to incorporate API call in translation code file.

API.

 axios
      .get(
        'http://localhost:8080/file_download/' +
          navigator.lnaguage
      )
      .then((res) => {
        console.log(res.data);
        });
      });
  }

Below is my translation code fr static files. for ex in TRANSLATIONS_FR I need to store output of API.

i18file.js:-

import i18next from 'i18next';

const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');
import xios from 'axios';

import { TRANSLATIONS_FR } from './../public/locales/fr/fr.js';
import { TRANSLATIONS_EN } from '../public/locales/en/en.js';

i18next
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources: {
      en: TRANSLATIONS_EN,
      fr: TRANSLATIONS_FR,
    },
    fallbackLng: 'fr',
  });

i18next.changeLanguage(navigator.language);

export default i18next;

I have to insert that API code into i18file.js file. if browser detecting en then I have to call for english and assign in resources. if browser detecting frech then I have to do for same.

Could you please suggest. I will write the code.

Edit1:- I am writing below code and it is throwing error. Below API will send the json data from database. this data I am not storing in file but directly using.

http://localhost:8080//file_download/en
Below is the code

import i18next from 'i18next';
import Backend from 'i18next-http-backend';

const LanguageDetector = require('i18next-browser-languagedetector');
const initReactI18next = require('react-i18next');

 i18next
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    backend: {
       loadPath: 'http://localhost:8080//file_download/en' //this is API path which will return result.
    }, 
    resources: {
      en:res.data //I need to assign here.
    },
    fallbackLng: 'fr',
  });
  i18next.changeLanguage(navigator.language);
export default i18next;

How can I incorporate the API in above code and use its data for eg in en language.

Shruti sharma
  • 199
  • 6
  • 21
  • 67

4 Answers4

3
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import backend from 'i18next-http-backend';
import api from "../api";

 var lang=navigator.language;

let loadResources= apiDelegate.getTranslations(lang);
const backendOptions = {
  loadPath: 'http://localhost:8080/code/'+lang, 
  request: (options, url, payload, callback) => {
    try {
      loadResources.then((result) => {
        callback(null, {
          data: result,
          status: 200, 
        });
      });
    } catch (e) {
      console.error(e);
      callback(null, {
        status: 500,
      });
    }
  },
};

i18n
  .use(LanguageDetector)
  .use(backend)
  .init({
    backend: backendOptions,
    fallbackLng: "fr",
    debug: false,
    load:"languageOnly",
    ns: ["translations"],
    defaultNS: "translations",
    keySeparator: false, 
    interpolation: {
      escapeValue: false, 
      formatSeparator: ","
    },
    react: {
      wait: true
    }
});
i18n.changeLanguage(navigator.language);
export default i18n;
Shruti sharma
  • 199
  • 6
  • 21
  • 67
  • I tried the same solution and it work fabulously well for init but wile I am calling changeLanguage, it is not re-rendering the page and not calling the api endpoint. Can you help in this? – Ankur Gupta Apr 13 '22 at 12:23
  • hi ankur , can you please help me with the loadPath , i am trying to understand why is it 'http://localhost:8080/code/'+lang , is this just the request url , and what is the expected response from the api call ? – Sarthak Gupta Jan 18 '23 at 06:00
2

Updated As await at top level is not supported

I would suggest to use another plugin i18next-http-backend as i18next has mentioned here

You need to install the plugin first npm i i18next-http-backend

Then just define the backend. There are some examples here

// import { TRANSLATIONS_FR } from './../public/locales/fr/fr.js';
// import { TRANSLATIONS_EN } from '../public/locales/en/en.js';
import Backend from 'i18next-http-backend';

i18next
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    backend: {
       loadPath: 'http://localhost:8080/file_download/{{lng}}/{{ns}}.json'
    }, // your backend options.
    // More info here: https://github.com/i18next/i18next-http-backend
    resources: {
      en,
      fr
    },
    fallbackLng: 'fr',
  });

i18next.changeLanguage(navigator.language);

export default i18next;
taile
  • 2,738
  • 17
  • 29
0

you don't need to write http://localhost:8080 as prefix of your get URL. just an / refers to public folder. just change your axios URL in API file to :

 axios
      .get(
        '/file_download' +
          navigator.lnaguage
      ) + '.json' // or any other format that your language file is
      .then((res) => {
        console.log(res.data);
        });
      });
  }
0

There's a great article explaining exactly how to adapt your code to load the translations via api here: https://dev.to/adrai/how-to-properly-internationalize-a-react-application-using-i18next-3hdb#separate

It introduces the i18next-http-backend module, shows you where to place the translation files: enter image description here

and how to adapt the code:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';

i18n
  // i18next-http-backend
  // loads translations from your server
  // https://github.com/i18next/i18next-http-backend
  .use(Backend)
  // detect user language
  // learn more: https://github.com/i18next/i18next-browser-languageDetector
  .use(LanguageDetector)
  // pass the i18n instance to react-i18next.
  .use(initReactI18next)
  // init i18next
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init({
    debug: true,
    fallbackLng: 'en',
    interpolation: {
      escapeValue: false // not needed for react as it escapes by default
    }
  });

export default i18n;

The full example can be found here.

—-

Alternatively, you can also lazy load the translations like this: https://github.com/i18next/i18next-resources-to-backend#you-can-also-lazy-load-the-in-memory-translations-ie-when-using-webpack


btw: i18next-http-backend is also able to inject a custom request function: https://github.com/i18next/i18next-http-backend#backend-options enter image description here

like here: https://github.com/i18next/i18next-http-backend/issues/34#issuecomment-729908814

adrai
  • 2,495
  • 1
  • 15
  • 18
  • The alternative with the custom request option is probably the best for your usecase: https://github.com/i18next/i18next-http-backend/issues/34#issuecomment-729908814 – adrai Jan 23 '22 at 12:27