React i18next and correct way of changing language
According to the documentation, you shouldn't need to specify the language yourself:
import i18next from 'i18next';import LngDetector from 'i18next-browser-languagedetector';i18next .use(LngDetector) .init({ detection: options });
And according to this piece of source in i18next
, it indeed uses the detection capabilities of the plugin:
if (!lng && this.services.languageDetector) lng = this.services.languageDetector.detect();
Is this the correct way of doing it?
So, no, it isn't . Let the plugin do it's job. :)
Hopefully this helps someone in the future. The documentation doesn't exactly give you the full picture of how to set up detection, and then I found a closed Github issue where several people were asking a reasonable question, and the maintainers were kinda rude in their responses but also happened to supply a link that should have been in the documentation - but is referenced absolutely no where outside of that Github comment. That example cleared up my issue with a few small adjustments from what the current documentation states to do.
I was then able to get language detection in my url with https:www.domain.com?lng=es
as well as when using a browser extension that let me change the browser language.
Heres my working i18n.ts
file:
import i18n from 'i18next'import LanguageDetector from 'i18next-browser-languagedetector'import { initReactI18next } from 'react-i18next'import XHR from "i18next-http-backend" // <---- add thisimport commonDe from './locales/de/common.json'import commonEn from './locales/en/common.json'import commonEs from './locales/es/common.json'import commonFr from './locales/fr/common.json'const resources = { de: { common: commonDe }, en: { common: commonEn }, es: { common: commonEs }, fr: { common: commonFr }}const options = { order: ['querystring', 'navigator'], lookupQuerystring: 'lng'}i18n .use(XHR) // <---- add this .use(LanguageDetector) .use(initReactI18next) .init({ // lng: 'en' // <--- turn off for detection to work detection: options, resources, ns: ['common'], defaultNS: 'common', fallbackLng: 'en', supportedLngs: ['de', 'en', 'es', 'fr'], interpolation: { escapeValue: false, }, debug: false, })export default i18n
(bonus help - if theres anyone jammed up on this part)
I am working in a Next.js project, and the above file was loaded in the project-root/pages/_app.tsx
file like this:
import React from 'react'import { AppProps } from 'next/app'import '../i18n/i18n'import '../public/styles.css'const TacoFridayApp = ({ Component, pageProps}: AppProps): JSX.Element => { return <Component {...pageProps} />}export default TacoFridayApp
I think you are very close. You can just set i18n
with fallback language initially. And then after loading saved language information for localstorage or localforage or whatever storage, call i18nInstance.changeLanguage(lng)
.