Internationalization With vue-i18n

Translations, Plurals, and Date/Number Formatting

Internationalization With vue-i18n

vue-i18n is the official translation library — message bundles, $t() in templates, switchable locale at runtime.

4 min read Level 2/5 #vue#i18n#translation
What you'll learn
  • Install vue-i18n@9
  • Set up message bundles and locale
  • Translate text with t() and $t()

vue-i18n is the de-facto translation library for Vue. It handles message lookups, named placeholders, pluralization, and number/date formatting.

Install

npm i vue-i18n@9

Configure

Create the instance and register it with your app.

// src/i18n.ts
import { createI18n } from 'vue-i18n'

export const i18n = createI18n({
  legacy: false, // use Composition API mode
  locale: 'en',
  fallbackLocale: 'en',
  messages: {
    en: {
      hi: 'Hi {name}',
      apples: 'no apples | one apple | {count} apples',
    },
    fr: {
      hi: 'Salut {name}',
      apples: 'aucune pomme | une pomme | {count} pommes',
    },
  },
})
// src/main.ts
import { i18n } from './i18n'
createApp(App).use(i18n).mount('#app')

In Components

Inside <script setup>:

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()
</script>

<template>
  <p>{{ t('hi', { name: 'Ada' }) }}</p>
  <p>{{ t('apples', 3) }}</p>
  <button @click="locale = locale === 'en' ? 'fr' : 'en'">
    Switch
  </button>
</template>

$t works directly in templates too if you don’t need it in scripts:

<p>{{ $t('hi', { name }) }}</p>

Number & Date Formatting

createI18n({
  legacy: false,
  locale: 'en',
  numberFormats: {
    en: { currency: { style: 'currency', currency: 'USD' } },
  },
})

// in component:
const { n } = useI18n()
n(1999.5, 'currency')   // "$1,999.50"

Pair with Vite plugin @intlify/unplugin-vue-i18n to load locale messages from JSON/YAML files and split them per chunk.

Unit Testing With Vitest →