vue-i18n
vue-i18n copied to clipboard
[Proposal] Modules and lazy loading
First let's build the modules
// houses/lang/en.js
// This is a locale which belongs to the module *houses*
export default {
messages: {
// translation keys start at this level
houses: {
house: 'casa',
hall: 'pasillo',
bath: 'baño',
...
}
}
}
import en from './en.js';
// This is a module
const houseModule = {
en: () => import('./houses/lang/en.js'),
es: () => import('./houses/lang/es.js'),
// We can also load locales without lazy loading
de,
...
}
When i18n is created, it accepts modules as configuration parameters.
const i18n = new VueI18n({
locale: 'en',
fallbackLocale: 'en',
modules: {
houses: houseModule,
}
})
It integrates nicely with vue-router. This router guard for languages, allows you to declare the localeModules
meta property to lazily load locales from that module for a particular route.
// routes.js
import houseLangs from './houses/lang/index.js';
const router = new VueRouter({
routes: [{
path: '/:lang/houses',
name: 'houses',
component: () => import('./components/houses.vue'),
props: true,
meta: {
// Tells route guard to load languages from this module only in this route and its children
localeModules: {
houses: houseLangs,
cars: {
en: () => import('./cars/lang/en.js'),
es: () => import('./cars/lang/es.js'),
...
}
},
},
children: [
...
],
}],
})
There is a working demo available. Instructions can be found in the repo.
Why modules?
With sharedMessages
, components can selectively load the translation keys they need, but they have to load them for all locales, even if many locales are not used.
vue-i18n provides methods to dynamically register locales like setLocaleMessage
, which can easily be used to selectively load locales. By default, they provide no structure to break down translation keys into more specific groups.
Modules provide an structure on top of dynamic vue-i18n methods. Modules can be lazy loaded in a similar way to route components and vuex stores. With modules, you can load only the locales that are strictly needed for the modules that are active.
Summary: sharedMessages
can selectively load groups of translations keys, vue-i18m methods can selectively load locales, and modules can do both.
Notes
In this example, VueI18n instances should be called with i18n.setLocale(locale)
where i18n.locale = locale
was previously used. The reason is that setLocale
calls async module loaders and returns a promise.
This is not the only possible solution. Another alternative is to listen to i18n.locale
changes and trigger language loaders. Then create a method i18n.onReady(callback, onReject)
to know when both locale and fallbackLocale are loaded in all languages. I'm just bad at Vue.
I'm currently building a large application on Vue and being able to load language files dynamically in a modular system for each route is a must. Making it work like modules presented on this proposal make this possible.
Your solution seems like a life-saver, it was just what I was looking for, I will try implement it on my side as well.
Is there any news on such feature being implemented into the plugin?
Bump, any news on this? React i18n has similar feature.