I integrated i18next in my NextJS application for translations. I support 2 locales: en and fr, with en as a fallback language.
i18n/index.ts
import { createInstance } from 'i18next'
import resourcesToBackend from 'i18next-resources-to-backend'
import { initReactI18next } from 'react-i18next/initReactI18next'
import { defaultNS, getOptions } from './settings'
const initI18next = async (lang: string, ns: string) => {
const i18nInstance = createInstance()
await i18nInstance
.use(initReactI18next)
.use(resourcesToBackend((language: any, namespace: any) => import(`./locales/${language}/${namespace}.json`)))
.init(getOptions(lang, ns))
return i18nInstance
}
export async function useTranslation(lang: string, ns: string = defaultNS, options: any = {}) {
const i18nextInstance = await initI18next(lang, ns)
return {
t: i18nextInstance.getFixedT(lang, Array.isArray(ns) ? ns[0] : ns, options.keyPrefix),
i18n: i18nextInstance
}
}
i18n/settings.ts
export const fallbackLng = 'en'
export const languages = [fallbackLng, 'fr']
export const cookieName = 'LANG'
export const defaultNS = 'translation'
export function getOptions (lang = fallbackLng, ns = defaultNS) {
return {
// debug: true,
supportedLngs: languages,
fallbackLng,
lang,
fallbackNS: defaultNS,
defaultNS,
ns
}
}
In the folder i18n/locales i have a folder for each locale, containing the same namespaces.
In my main page.ts which is a server component, even if my locale is fr, i get the en translations since it’s the fallback language.
export default async function Home({
params
}:{
params: { lang: string },
}) {
console.log('home lang', params?.lang) // fr
const { t } = await useTranslation(params?.lang, 'home')
console.log('home t', t) // [Function: fixedT] { lng: 'fr', ns: 'home', keyPrefix: undefined }
console.log('home t(hero-title)', t('hero-title')) // gives me the en translation
// ...
}
I certainly missed something. Thanks for your insights.