We’re migrating our Meteor app from tap-i18n
to meteor-universe-i18n and I’m having a lot of trouble trying to dynamically load i18n JSON translation files. The package claims it’s a feature yet the documentation is quite lacking, doesn’t have an example, and seems to mention several different approaches.
The good news is everything is working as expected with the package if I load all the JSON translation files into the client
at once on startup:
// Client startup code
// Import i18n files used in app.
import "../../i18n/app.ar.i18n.json";
import "../../i18n/app.bn.i18n.json";
import "../../i18n/app.da.i18n.json";
// Plus twelve more languages...
All the callbacks work correctly and all the locales are automatically detected.
The problem is most of our users are English-speaking and adding the other fourteen JSON language files in the client at once adds about 5% onto the JS bundle size. So we want to dynamically load the JSON files when the respective language is selected.
The README mentions using JSON translation files to bypass calling i18n.addTranslation()
. This is working fine when loading them all in the client at build time.
In the API section it mentions using import('../path/to/i18n')
to dynamically import translation files. Our kneejerk implementation of this is to do this in the onChangeLocale
callback (which is also client
code):
i18n.onChangeLocale(function(newLocale) {
(async () => {
await import(`../../i18n/app.${newLocale}.i18n.json`);
reactiveLanguage.set(newLocale);
})();
});
This doesn’t seem to work because the dynamic import call import()
doesn’t work if a variable string is passed. I’m assuming this is because if at build time, the compiler doesn’t know what to import than those files are not available to be imported. I’m not super-savvy with dynamic imports, but I thought this would retrieve the dynamically imported resource from the server?
I even tried moving the i18n JSON files to a /public/i18n
folder and changing the code to:
await import(Meteor.absoluteUrl() + `i18n/app.${newLocale}.i18n.json`);
to see if that would serve them from the Meteor web server. But the dynamic import still fails saying it can’t find the resource. However I can click on the above link and see the JSON file load in my browser.
If dynamic import can only include things at runtime, what is the point of dynamic importing? What is it actually doing? I thought it kept any resources from being packed into the bundle and thus loads them dynamically from the server somehow.
Then there’s another API method called i18n.loadLocale(locale, params)
that mentions loading translation files from a remove server. My translation files are on my Meteor server so I’m assuming not to go this route?
So far all of the above is all in client code. The README also alludes to another approach of having a server version of i18n
that I assume loads all the JSON translation files on the server and then that can somehow “sync” to your client. There isn’t a lot of examples or explanation on how this works.
Anyone have a clue on how to do this?
Tagging some users that have posted in other i18n threads: @radekmie @waldgeist @zendranm