Open jbaldivieso opened 1 month ago
@jbaldivieso it may not fit to your needs/setup but I implemented it myself. I have a nuxt application where gettext is initialized within a plugin and if I change the language the whole application is reloaded (I guess this is needed for this approach)
// plugins/translate.ts
await gettext(nuxtApp.$i18n.locale.value)
// gettext.js
...
export default async function gettext(lang) {
const languageFile = await import(`../locales/dist/${lang}.json`);
return createGettext({
availableLanguages,
silent: true,
defaultLanguage: lang,
translations: languageFile,
provideDirective: false,
provideComponent: false,
});
}
@FlorianWerndl–Thank you very much for sharing this! I took a closer look at the source code, and it appears that createGettext
stores translations
as a reactive variable, complete with a getter and setter. So one is able to hot-swap the translation file on the fly (dynamically importing it as you suggest) without having to reload the app.
Since this doesn't seem like an edge case (right? the average user only wants an app/website in a single language), I think this process could be smoother/better documented.
Here is what worked for me:
const availableLanguages = {
en: "English",
es: "Español",
fr: "Francais",
}
const translations = {
// This is fake; upon initial load, we call `updateLanguage` below to import
// a *real* translation file. This prevents us from downloading the
// English translation if that's not our browser's preferred language.
en: { en: { stub: "stub" } }
}
export const gettext = createGettext({
defaultLanguage: "en",
availableLanguages,
translations,
})
export async function updateLanguage(lang: string) {
// Guard here against possible crazy imports
if (lang in availableLanguages) {
const trans = await import(`@/locales/translations/${lang}.json`)
gettext.translations = trans
gettext.current = lang
}
}
And then when the app mounts, I call logic that looks up/infers the language (cookie, local storage, request headers) and calls updateLanguage
asynchronously to set translations
to a meaningful translation file. (In my case, I'm using code splitting with manually chunks in rollup, so I have to make sure that each translation file is represented there in a separate chunk.)
It appears that, despite having specified
splitJson: true
in the config, ultimately all translations get minified into the same file for my app. It would be ideal to lazily load languages only upon their activation. Once you have multiple languages with nontrivial amounts of content, the file size really starts to add up, with no benefit to your average single-language user.