Skip to content
Search

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:

this.$t("message.hello")

Single file components

If you use Vue CLI 3.x:

vue add i18n

Otherwise, install vue-i18n-loader directly:

yarn add -D @intlify/vue-i18n-loader

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:

import i18n from 'path/to/i18n';

const state = {
    title: i18n.t('title'),
};

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.

No results matching "<strong>{{ search }}</strong>". Press <kbd>enter</kbd> to create a new one

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.

this.$vuetify.lang.current = lang;
this.$i18n.locale = lang;

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.

this.$vuetify.lang.current = 'ko';

Then, since this.$vuetify.lang.current is being watched using @Watch, the language of those components changes all at once.

See also

Favorite site

author Zer0 sitemap