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
Related
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;
I have the following i18n setup on my react
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import {initReactI18next} from 'react-i18next'
import Backend from 'i18next-http-backend';
i18n
.use(initReactI18next)
.use(LanguageDetector)
.use(Backend)
.init({
backend: {
loadPath: `test.com`,
},
react: {
useSuspense: false
},
whitelist: ['en', 'fr', 'es'],
fallbackLng: ['en'],
detection: {
order: ['cookie', 'navigator'],
lookupCookie: 'i18nextLng',
caches: ['cookie'],
cookieOptions: { path: '/', sameSite: 'strict' },
checkWhitelist: true
}
})
export default i18n
I have a unique product with some information as price I would like to use as defaultVariables
Reading the doc I can change the inti config adding
{
interpolation: {
defaultVariables: {price: 100}
}
}
and then {{price}} should be available on all my translations
This part is working great.
But I am getting the product from a server call and I can not find any way to update the defaultVariables once i18n has been initialized
Officially, the only way to have defaultVariables injected is via init function.
This means you have to load those values before calling init(), and then pass them via init options.
But....
you can try to do this:
i18next.services.interpolator.options.interpolation.defaultVariables = { price: 100 }
This may work, but this is for sure unsupported and not recommended.
btw: the whitelist option was replaced with supportedLngs: https://www.i18next.com/misc/migration-guide#removed-deprecated
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
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,
},
})
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;