Implementing Internationalization in Vue 3 with vue-i18n

vue-i18n serves as the standard solution for adding internationalization support to Vue aplications. This guide demonstrates how to configure and use this library in a Vue 3 project.

Installation

Execute the following command in your Vue project directory:

pnpm install vue-i18n

Configuration

1. Directory Structure

This example supports Chinese, English, and Japanese languages. Create a locale folder under src containing the following files: index.ts, en.ts, ja.ts, and zh.ts. The index.ts file serves as the i18n configuration, while the language-specific files contain translation messages. Maintaining separate files keeps translations organized as the application grows.

2. index.ts Configuration

import {createI18n} from "vue-i18n";
import enMessages from './en.ts'
import jaMessages from './ja.ts'
import zhMessages from './zh.ts'

const i18n = createI18n({
    locale:'ja',
    legacy:false,
    messages:{
        en:enMessages,
        ja:jaMessages,
        zh:zhMessages
    }
})
export default i18n

Critical note: set legacy to false. Failing to do so results in errors when invoking i18n APIs in other components.

3. Language Message Files

en.ts
const enMessages = {
    greeting: {
        welcome: 'welcome world'
    }
}
export default enMessages
ja.ts
const jaMessages = {
    greeting: {
        welcome: 'こんにちは、世界'
    }
}
export default jaMessages
zh.ts
const zhMessages = {
    greeting: {
        welcome: '你好'
    }
}
export default zhMessages

This demo uses minimal translation content. Expand these files with additional keys as needed.

Integration

Before using i18n in components, register the configured i18n instance in the Vue main entry file.

main.ts
import { createApp } from 'vue'
import App from './App.vue'

import i18n from "./locale/index";

const app = createApp(App)

app.use(i18n)

app.mount('#app')
Component Usage
<template>
    <div style="height: 50%;display: flex;justify-content: center;align-items: center">
        <div>{{ $t('greeting.welcome') }}</div>
    </div>
</template>

Usage within templates is straightforward. The $t() function accepts dot-notation keys matching the translation object structure. In this example, the greeting object contains the welcome key, accessed via $t('greeting.welcome').

Language Switching

Dynamic language switching requires modifying the locale property. Access the useI18n composable to retrieve and update the current locale value.

<template>
  <div style="width: 100%;height: 100%">
    <div style="display: flex;justify-content: center">
      <el-select
          v-model="selectedLang"
          placeholder="Select"
          size="large"
          style="width: 240px"
          @change="handleLanguageChange"
      >
        <el-option label="中文" value="zh"/>
        <el-option label="English" value="en"/>
        <el-option label="日本語" value="ja"/>
      </el-select>
    </div>
    <div style="height: 50%;display: flex;justify-content: center;align-items: center">
      <div>{{ $t('greeting.welcome') }}</div>
    </div>
  </div>
</template>

<script setup>
import {useI18n} from 'vue-i18n'

const {locale} = useI18n()

const selectedLang = ref('')

onMounted(() => {
  selectedLang.value = locale.value
})

const handleLanguageChange = (value) => {
  locale.value = value
}
</script>

Tags: Vue 3 vue-i18n Internationalization i18n frontend

Posted on Thu, 07 May 2026 18:54:46 +0000 by djsl