When you want to include i18n
in your react component library, but the two use cases of i18next
conflict with one another — long story short, you need I18nextProvider
.
Step 1: create i18next instance
In component library, we will need to create an i18next
instance, and not use initReactI18next
to initialize it, because initReactI18next
generates a global config, which will pollute the outside use cases.
import i18next from 'i18next'
// Note that we are using createInstance here
const i18n = i18next.createInstance(
{
lng: 'en',
fallbackLng: 'en',
ns: ['translation'],
defaultNS: 'translation',
react: { useSuspense: false },
interpolation: { escapeValue: false },
resources: {
en: { translation: require('./locales/en/translation.json') },
fr: { translation: require('./locales/fr/translation.json') },
},
},
// We must provide a function as second parameter, otherwise i18next errors
(err, t) => {
if (err) return console.log(err)
},
)
export default i18n
Step 2: I18nextProvider
import i18next from 'i18n'
import { useTranslation, I18nextProvider } from 'react-i18next'
export default function FantasticComponent(props) {
// here we make sure that the scope of translations is confined within this component. Translation method t() is not available yet
return (
<I18nextProvider i18n={i18next}>
<GridPage {...props} />
</I18nextProvider>
)
}
function FantasticComponentWithContext({ language }) {
// Within i18n context, we now have access to t()
const { t, i18n } = useTranslation()
// here we pass in `language` as one of the props so we can sync its change:
useEffect(() => {
i18n.changeLanguage(language)
}, [i18n, language])
return <h1>{t('blast')}</h1>
}
Could provide an example how to use consumer i18n instance in component library?