Lazy loading
Loading all of your localization files at once is overkill and unnecessary.
Lazy loading or asynchronously loading the localization files is really easy when using bundler.
Let´s assume we have a project directory similar to the one below:
├── dist
├── index.html
├── package.json
├── src
│ ├── App.vue
│ ├── components
│ ├── i18n.js
│ ├── index.css
│ ├── locales
│ │ ├── en.json
│ │ └── ja.json
│ ├── main.js
│ ├── pages
│ │ ├── About.vue
│ │ └── Home.vue
│ └── router.js
The pages
folder is where our arbitrary Vue component files like the About.vue
, router inits, i18n inits and other reside. The locales
folder is where all of our localization files reside, and In i18n.js
, the functions for i18n-related process are defined as follows:
import { nextTick } from 'vue'
import { createI18n } from 'vue-i18n'
export const SUPPORT_LOCALES = ['en', 'ja']
export function setupI18n(options = { locale: 'en' }) {
const i18n = createI18n(options)
setI18nLanguage(i18n, options.locale)
return i18n
}
export function setI18nLanguage(i18n, locale) {
if (i18n.mode === 'legacy') {
i18n.global.locale = locale
} else {
i18n.global.locale.value = locale
}
/**
* NOTE:
* If you need to specify the language setting for headers, such as the `fetch` API, set it here.
* The following is an example for axios.
*
* axios.defaults.headers.common['Accept-Language'] = locale
*/
document.querySelector('html').setAttribute('lang', locale)
}
export async function loadLocaleMessages(i18n, locale) {
// load locale messages with dynamic import
const messages = await import(
/* webpackChunkName: "locale-[request]" */ `./locales/${locale}.json`
)
// set locale and locale message
i18n.global.setLocaleMessage(locale, messages.default)
return nextTick()
}
The following three functions are exported:
setupI18n
setI18nLanguage
loadLocaleMessages
NOTE
This code example also shows how to handle it outside of the component using the global
property of i18n instance. About i18n instance, see the API Reference
The setupI18n
function takes the same options as createI18n
, creates an instance of i18n with those options, executes the setI18nLanguage
function, and returns the i18n instance.
The setI18nLanguage
function sets the language by setting the locale of the parameter i18n
to the value of the parameter locale
. Besides, this function has the utility of setting the lang
attribute of the HTML document to the value of the parameter locale
. As noted in the comments, like the HTTP client, you can also set the language
The loadLocaleMessages
function is what we will actually use to change the languages. Loading the new files is done via the import
function, which is generously provided by webpack and it allows us to load files dynamically, and because it uses promises we can easily wait for the loading to finish.
You can learn more about the import function in the webpack documentation.
Using the loadLocaleMessages
function is straightforward. A common use case is inside a vue-router beforeEach hook.
Here the code for the vue-router beforeEach hook part of router.js
:
// navigation guards
router.beforeEach(async (to, from, next) => {
const paramsLocale = to.params.locale
// use locale if paramsLocale is not in SUPPORT_LOCALES
if (!SUPPORT_LOCALES.includes(paramsLocale)) {
return next(`/${locale}`)
}
// load locale messages
if (!i18n.global.availableLocales.includes(paramsLocale)) {
await loadLocaleMessages(i18n, paramsLocale)
}
// set i18n language
setI18nLanguage(i18n, paramsLocale)
return next()
})