The problem: I need to support multiple languages in my React application. When I call i18next.changeLanguage(…), nothing happens in the application. This is how the code is structured:
This is the 18next configuration. Probably have a lot of redundant properties, but I have tried adding stuff I did not have that others pointed out in their problems on this site, just to make sure I was not missing anything.
const resources = {
sv: {
translation: sv,
},
en: {
translation: en,
}
};
i18next
.use(initReactI18next)
.init({
ns: ['translation'],
defaultNS: 'translation',
debug: true,
lng: 'sv',
fallbackLng: 'en',
supportedLngs: ['sv', 'en'],
resources: resources,
});
export default i18next;
Then I have a language selector component, which is basically just a dropdown that sends the selected language to a LanguageService.
private selectLanguage(lang: string): void {
LanguageService.setLanguage(lang);
}
The LanguageService picks up the change and propagates it to its internal subject, which will trigger its public observer (using RXJS here).
class LanguageServiceImpl {
private languageChangedSub = new ReplaySubject<string>();
public languageChanged$ = this.languageChangedSub.asObservable();
public setLanguage(lang: string): void {
i18next.changeLanguage(lang, () => {
moment. Locale(lang);
this.languageChangedSub.next(lang);
});
}
}
And finally, the App component, which is observing the language change acts on it:
LanguageService.languageChanged$
.pipe(takeUntil(this.unmount.unmount$))
.subscribe(() => this. Render());
But this has no effect whatsoever.. the language does not change.
I have even tried wrapping the App in an i18nextProvider like so:
<React.StrictMode>
<I18nextProvider i18n={i18next}>
<BrowserRouter>
<App />
</BrowserRouter>
</I18nextProvider>
</React.StrictMode>
A lot of the examples use functional components and hooks, but I am doing this with class components because that it is how I function (pun intended), so there is probably something I am missing or not grasping in the i18next concept. Please help.