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.
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.