Shruti sharma
Shruti sharma

Reputation: 211

how to incorporate API data in i18next instead of static file

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.

Upvotes: 2

Views: 7474

Answers (5)

Mohasin Akonda
Mohasin Akonda

Reputation: 31

Here is my working code with typescript

// i18n.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import i18HttpLoader from "i18next-http-backend";
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
i18n.use(initReactI18next)
    .use(i18HttpLoader)
    .init({
        react: {
            useSuspense: false,
        },
        backend: {
            loadPath: `www.example.com/translations/manage/{{lng}}`,//endpont
            request: (
                options: any,
                url: string,
                payload: AxiosRequestConfig<any> | undefined,
                callback: (
                    arg0: null,
                    arg1: AxiosResponse<any, any> | null
                ) => void
            ) => {
                axios
                    .get(url, payload)
                    .then((response) => {
                        callback(null, response);
                    })
                    .catch((error) => {
                        //you can use a default language josn file if error occurs 
                         //or something wrong with your json file
                        const defaultTranslation = require("locales/en.json");
                        const response: any = {
                            status: 200,
                            statusText: "OK",
                            data: defaultTranslation,
                        };
                        callback(null, response);
                    });
            },
        },
        
        lng: "en",
        fallbackLng: "en",
        interpolation: {
            escapeValue: false,
        },
    });

export default i18n;

Upvotes: 0

Shruti sharma
Shruti sharma

Reputation: 211

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;

Upvotes: 3

adrai
adrai

Reputation: 3178

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

Upvotes: 0

taile
taile

Reputation: 2776

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;

Upvotes: 3

Mersad Mirgholami
Mersad Mirgholami

Reputation: 156

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);
        });
      });
  }

Upvotes: 0

Related Questions