Local Scope Based Localization
i18n component options
In 'Scope and Locale Changing’, Vue I18n has two scope concepts, global scope and local scope.
In general, locale info (e.g. locale
,messages
, etc) is set as option of createI18n
and it sets (install) with app.use
. To sum up, you use global scope translation functions $t
and $tc
to localize them.
Sometimes it is necessary to localize per component while still managing the resources of the local messages. In this case it can be useful to localize each local scope using i18n component option on the component instead of the global scope.
The following is an example of local scope based localization:
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
// setting locale info used by global scope as an options
const i18n = createI18n({
locale: 'ja',
messages: {
en: {
message: {
hello: 'hello world',
greeting: 'good morning, world!'
}
},
ja: {
message: {
hello: 'こんにちは、世界',
greeting: 'おはよう、世界!'
}
}
}
})
// define component
const Component1 = {
template: `
<div id="component">
<h1>Component1</h1>
<p>Component1 locale messages: {{ $t("message.hello") }}</p>
<p>Fallback global locale messages: {{ $t("message.greeting") }}</p>
</div>
`,
i18n: {
messages: {
en: { message: { hello: 'hello component1' } },
ja: { message: { hello: 'こんにちは、component1' } }
}
}
}
const app = createApp({
components: { Component1 }
})
app.use(i18n)
app.mount('#app')
Template:
<div id="app">
<h1>Root</h1>
<p>{{ $t("message.hello") }}</p>
<Component1 />
</div>
Outputs the following:
<div id="app">
<h1>Root</h1>
<p>こんにちは、世界</p>
<div class="component">
<p>Component1 locale messages: こんにちは、component1</p>
<p>Fallback global locale messages: おはよう、世界!</p>
</div>
</div>
As in the example above, if the component doesn't have the locale message, it falls back to global scope. As explained the here, due to the locale
of local scope inherits from global scope, so the component uses the language set in global scope (in the above example: locale: 'ja'
)
And also, as explained the here, note that, by default, falling back to global scope generates two warnings in the console:
[intlify] Not found 'message.greeting' key in 'ja' locale messages.
[intlify] Fall back to translate 'message.greeting' with root locale.
If you want to localize using the component locale, you can do that with sync: false
and locale
in the i18n
component option.
Shared locale messages for components
Sometimes you may want to import shared locale messages for certain components, not fallback from locale messages of global scope (e.g. common messages of certain feature for components).
You can use sharedMessages
options of i18n
.
Common locale messages example:
export default {
en: {
buttons: {
save: "Save",
// ...
}
},
ja: {
buttons: {
save: "保存",
// ...
}
}
}
Components:
import commonMessage from './locales/common' // import common locale messages
export default {
name: 'ServiceModal',
template: `
<div class="modal">
<div class="body">
<p>This is good service</p>
</div>
<div class="footer">
<button type="button">{{ $t('buttons.save') }}</button>
</div>
</div>
`,
i18n: {
messages: { ... },
sharedMessages: commonMessages
}
}
If sharedMessages
option is specified along with the messages
option, those messages will be merged into locale messages into the VueI18n instance of the target component.