Vue I18n
lastmod 2022-04-27created 2020-06-1226 edits
Vue I18n is internationalization plugin for Vue.js.
in JavaScript
To use it directly in JavaScript:
Single file components
If you use Vue CLI 3.x:
Otherwise, install vue-i18n-loader directly:
| WARNING |
| When using Vue CLI, if you configure the config files yourself, it is very likely not to work properly ... -_- ;; |
YAML Example
<i18n locale="en" lang="yaml">
hello: "hello world!"
</i18n>
<i18n locale="ja" lang="yml">
hello: "こんにちは、世界!"
</i18n>
Including a JSON file
<i18n src="@/translations/common/lang.json"></i18n>
<i18n locale="ja" lang="yml">
hello: "こんにちは、世界!"
</i18n>
Simple Example
HTML:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script>
<div id="app">
<p>{{ $t("message.hello") }}</p>
</div>
JavaScript:
// If using a module system (e.g. via vue-cli), import Vue and VueI18n and then call Vue.use(VueI18n).
// import Vue from 'vue'
// import VueI18n from 'vue-i18n'
//
// Vue.use(VueI18n)
// Ready translated locale messages
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: 'ja', // set locale
messages, // set locale messages
})
// Create a Vue instance with `i18n` option
new Vue({ i18n }).$mount('#app')
// Now the app has started!
How to use it outside Vue components
import Vue from 'vue';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
const messages = {
en: {
message: {
hello: 'hello world',
},
},
};
const i18n = new VueI18n({
locale: 'en',
messages,
});
export default i18n;
Import i18n in your store, then you can use the .t() function to translate or any other.
store.js:
How to include HTML tags
You need to use the <i18n> tag in the template.
First, let's look at how to apply the following sentence.
Add them as named arguments as follows. Do not include HTML TAGs in i18n strings.
<i18n lang="yaml">
en:
no_features: "No results matching \"{search}\". Press {key} to create a new one."
ko:
no_features: "\"{search}\" 와 일치하는 결과가 없습니다. {key} 키를 눌러 새 항목을 만듭니다."
</i18n>
Then, when using it, add it in the template using <i18n>.
<template>
<!-- ... -->
<i18n path="no_features" tag="span">
<template #search>
<strong>{{ searchFeature }}</strong>
</template>
<template #key>
<kbd>enter</kbd>
</template>
</i18n>
<!-- ... -->
</template>
Troubleshooting
Language translation not being applied
There are a few things to check.
- Think carefully about where the instance is created. Don't add it in places like a constructor. Insert the code where it is actually called.
Fall back to translate the keypath 'message' with root locale
[vue-i18n] Value of key 'message.greeting' is not a string!
[vue-i18n] Fall back to translate the keypath 'message.greeting' with root locale.
If the warning above is noisy, add the silentFallbackWarn: true option when initializing the VueI18n instance.
WebStorm SFC i18n yaml error
In WebStorm, using vue-i18n with yaml in a Single-file component is flagged as a syntax error.
<i18n lang="yaml">
_languages: &languages
en: "English"
ko: "한국어"
en:
<<: *languages
header: "Translations"
ko:
<<: *languages
header: "언어선택"
</i18n>
This code compiles normally.
So work around it as follows.
Changes not applied when switching language
To change the current language of vuetify, change it as follows.
If the language still doesn't change automatically after doing that, check whether you changed it in a child component. It seems the change is applied to the screen immediately only for child components <- needs checking!
Checked it... it's not a child component problem,,, presumably a reactive reference problem.
- vue-i18n is used locally in components via vue-i18n-loader.
- Using
this.$i18n.locale = 'ko';applies only to the component where it was used. - So every component must use
this.$i18n.locale = 'ko';so that a reactive event is triggered.
This also needs checking !!!
As a temporary fix, I changed it as follows.
Created a BaseI18n.ts file as follows.
import { Vue, Watch } from 'vue-property-decorator';
export default class BaseI18n extends Vue {
@Watch('$vuetify.lang.current')
updateI18n(newVal: string, oldVal: string) {
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
this.$i18n.locale = newVal;
}
}
It's not the component !!! The component !
Go to every component that uses <i18n> and inherit from the class above instead of Vue.
<script lang="ts">
import BaseI18n from '@/translations/BaseI18n';
import { Component, Prop, Emit, Watch } from 'vue-property-decorator';
import MenuTranslate from '@/components/MenuTranslate.vue';
import { mdiThemeLightDark, mdiApi } from '@mdi/js';
@Component({
components: {
MenuTranslate
}
})
export default class ButtonsConfigPublic extends BaseI18n {
// ...
}
Where the language needs to change, run the following.
Then, since this.$vuetify.lang.current is being watched using @Watch, the language of those components changes all at once.
See also
- vue
- vue-i18n-jest - A testing approach combining vue i18n, jest, and vue test utils.