How to change language locally in react-i18next? - reactjs

I'm trying to give user an option to specify language of generated receipt while keeping the language of the app the same. How would I change the language only for receipt component? i18n.changeLanguage does it globally.
If it helps, here is my i18n config:
i18n
.use(Backend)
.use(initReactI18next)
.init({
ns: ["translation", "login", "orders", "products", "invoices"],
defaultNS: "translation",
lng: "sl",
fallbackLng: "en",
debug: process.env.NODE_ENV === "development",
interpolation: {
escapeValue: false,
},
react: {
useSuspense: true,
wait: true,
},
});

You can use the getFixedT method to get translations of a particular object in a given language regardless of the global language. Here is an example:
en.json
{
nested: {
object: {
...
}
}
}
App.jsx
import { getFixedT } from "i18next";
const App = () => {
const fixedT = getFixedT("en");
const templateData = fixedT("nested.object", {
returnObjects: true,
});
}
References
i18next official documentation: getFixedT

Related

React reload imported translations from Laravel using i18n and Laravel Translations Loader

I am working on a project with Laravel/React. I am loading the translations from Laravel using kirschbaum-development/laravel-translations-loader and i18n. When I programmatically add a new translation string in the lnguage files it doesn't load it until I reload the current page including the browser cache. Is there a possibility to reload the languageBundle without page reload?
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import languageBundle from '#kirschbaum-development/laravel-translations-loader!#kirschbaum-development/laravel-translations-loader';
i18n
// 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,
lng: "ro",
fallbackLng: 'en',
resources: {
//de refacut dinamic
bg: {
translation: languageBundle.bg
},
de: {
translation: languageBundle.de
},
en: {
translation: languageBundle.en
},
es: {
translation: languageBundle.es
},
fr: {
translation: languageBundle.fr
},
hu: {
translation: languageBundle.hu
},
ro: {
translation: languageBundle.ro
},
},
supportedLngs: ['bg', 'de', 'en', 'es', 'fr', 'hu', 'ro'],
// backend: {
// loadPath: 'lang/{lng}/{ns}.php'
// },
// react: {
// wait: false,
// bindI18n: 'languageChanged loaded',
// bindStore: 'added removed',
// nsMode: 'default'
// },
});
export default i18n;

How can I define i18n language code (same language but different version) in React?

I have a problem about defining different kind of language through i18n in my React App.
I have es-MX, es-ES , zh-CN and lastly zh-TW language codes in my language array.
I have no idea how I can define them in i18n process.
How can I do that?
Here is my i18n code snippet shown below.
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n.use(initReactI18next).init({
resources: {
...
},
fallbackLng: 'en',
ns: ['translations'],
defaultNS: 'translations',
keySeparator: false,
interpolation: {
escapeValue: false,
formatSeparator: ','
},
react: {
wait: true
}
});
export default i18n;
Here is my answer shown below.
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n.use(initReactI18next).init({
resources: {
"en-MX": {
translations: {
}
},
"es-ES": {
translations: {
}
},
"zh-CN": {
translations: {
}
},
"zh-TW": {
translations: {
}
}
},
fallbackLng: 'en',
ns: ['translations'],
defaultNS: 'translations',
keySeparator: false,
interpolation: {
escapeValue: false,
formatSeparator: ','
},
react: {
wait: true
}
});
export default i18n;

How to update react-i18next language based on a state?

I know how to change react-i18next language, but this change would only be valid for the current session or device.
So, when changing the locale, I update i18next first to provide an immediate ux feedback and then make an api call to update the user profile in my database.
export async function useLocale(locale: Locale) {
const { i18n } = useTranslation();
const { updateProfile }= userService();
i18n.changeLanguage(locale);
return updateProfile({locale})
}
Now, how to make sure i18next fetches the locale from the user state on the next connection? My user state is stored in zustand:
export const userStore = create(() => ({ name: "Joe", locale: "en" }));
The i18nconfig is:
const languages = {
EN: "en",
FR: "fr",
};
const langDetectorOptions = {
order: ["cookie", "localStorage", "navigator"],
lookupCookie: "locale",
lookupLocalStorage: "locale",
caches: ["localStorage", "cookie"],
excludeCacheFor: ["cimode"],
checkWhitelist: true,
};
const resources = {
en: { translation: en },
fr: { translation: fr },
};
export default i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources,
lng: languages.EN,
detection: langDetectorOptions,
fallbackLng: languages.EN,
keySeparator: ".",
whitelist: [languages.EN, languages.FR],
interpolation: { escapeValue: false },
});
You may need to implement a custom language detector: https://www.i18next.com/misc/creating-own-plugins.html#languagedetector

How to change default value react-i18next (in localstorage)

I`am use backend and language detector, but:
In localstorage is written I18nextLng with the value en-US, how to make default value is I18nextLng with the value En
init and other settings - default documentation
.init({
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false,
},
})
I never used the language detector, but the way I set the default language is to set the lng key, and have resources obj
const resources = {
en: { translation: {...} },
fr: { translation: {...} }
}
.init({
resources,
lng: 'fr' // this is the default language. Try to put this
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false,
},
})

How can we load translations using api calls instead of having them defined in static jsons? How can this be done in React-i18next?

On using internationalization in React application, Need to load the language translation files on demand using api calls and not have them defined upfront. How can this be achieved by using React-i18next?
Tried out the normal translations being picked from static predefined files using React-i18next. Tried using xhr-backend but unable to find any sample to implement this requirement of on-demand load of translation related data.
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import backend from 'i18next-http-backend';
import axiosInstance from './helpers/Axios';
const loadResources=async(locale:string)=> {
return await axiosInstance().get('/translate-data/get', { params: { lang: locale } })
.then((response) => { return response.data })
.catch((error) => { console.log(error); });
}
const backendOptions = {
loadPath: '{{lng}}|{{ns}}',
request: (options:any, url:any, payload:any, callback:any) => {
try {
const [lng] = url.split('|');
loadResources(lng).then((response) => {
callback(null, {
data: response,
status: 200,
});
});
} catch (e) {
console.error(e);
callback(null, {
status: 500,
});
}
},
};
i18n
.use(LanguageDetector)
.use(backend)
.init({
backend: backendOptions,
fallbackLng: "en",
debug: false,
load:"languageOnly",
ns: ["translations"],
defaultNS: "translations",
keySeparator: false,
interpolation: {
escapeValue: false,
formatSeparator: ","
},
react: {
wait: true
}
});
export default i18n;
Request from backend options is used to call backend API using Axios.
import i18next from 'i18next';
import XHR from 'i18next-xhr-backend';
var language = i18next.language ||'en-US';
const backendOptions = {
type: 'backend',
crossDomain: false,
allowMultiLoading: false,
loadPath: `your-backend-api/?locale_code=${language}`
}
const options = {
interpolation: {
escapeValue: false, // not needed for react!!
},
initImmediate: false ,
debug: true,
lng: language,
fallbackLng: language,
// have a common namespace used around the full app
ns: ['translations'],
defaultNS: 'translations',
react: {
wait: false,
bindI18n: 'languageChanged loaded',
bindStore: 'added removed',
nsMode: 'default',
defaultTransParent: 'div',
},
};
options['backend'] = backendOptions;
i18next
.use(XHR)
.init(options)
export default i18next;

Resources