Breaking Changes in v12
Drop Legacy API mode
Reason: Legacy API mode was deprecated in v11 as announced in the v11 breaking changes. It was the API mode compatible with Vue I18n v8 for Vue 2, provided to smooth the migration from v8 to v9.
With v12, Legacy API mode has been completely removed. The legacy option in createI18n is no longer available, and all applications must use Composition API mode.
What's removed
legacy: trueoption increateI18nVueI18ninstance (the legacy interface)VueI18nOptionstypeallowCompositionoption (no longer needed as Composition API is the only mode)- Legacy-specific injection APIs that depended on
VueI18ninstance
Before (v11)
import { createI18n } from 'vue-i18n'
// Legacy API mode
const i18n = createI18n({
legacy: true, // This was the default in earlier versions
locale: 'en',
messages: {
en: { hello: 'Hello!' },
ja: { hello: 'こんにちは!' }
}
})
// Access via VueI18n instance
i18n.global.locale = 'ja'<!-- In Options API component -->
<template>
<p>{{ $t('hello') }}</p>
</template>
<script>
export default {
mounted() {
// Access via this.$i18n (VueI18n instance)
console.log(this.$i18n.locale)
this.$i18n.locale = 'ja'
}
}
</script>After (v12)
import { createI18n } from 'vue-i18n'
// Composition API mode (only mode available)
const i18n = createI18n({
locale: 'en',
messages: {
en: { hello: 'Hello!' },
ja: { hello: 'こんにちは!' }
}
})
// Access via Composer instance
i18n.global.locale.value = 'ja'<!-- Using Composition API -->
<template>
<p>{{ t('hello') }}</p>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
// Change locale
locale.value = 'ja'
</script><!-- Options API with useI18n in setup -->
<template>
<p>{{ t('hello') }}</p>
</template>
<script>
import { useI18n } from 'vue-i18n'
export default {
setup() {
const { t, locale } = useI18n()
return { t, locale }
}
}
</script>Migration
- Remove
legacy: trueoption fromcreateI18n - Change locale access from
i18n.global.localetoi18n.global.locale.value - Replace
this.$i18nusage withuseI18n()in setup function - Replace
this.$t()witht()fromuseI18n()
For detailed migration guide, see:
Drop Custom Directive v-t
Reason: This custom directive had already deprecated in warning about being dropped in v12. docs says, https://vue-i18n.intlify.dev/guide/migration/breaking11.html#deprecate-custom-directive-v-t
Change MissingHandler signature
Reason: Vue 3.6+ deprecates getCurrentInstance() API. The MissingHandler type previously received a ComponentInternalInstance as the third parameter, but this is no longer available.
Before (v11)
type MissingHandler = (
locale: Locale,
key: Path,
instance?: ComponentInternalInstance,
type?: string
) => string | void
const i18n = createI18n({
missing: (locale, key, instance, type) => {
// instance was ComponentInternalInstance
console.warn(`Missing: ${key}`, instance?.uid)
}
})After (v12)
type MissingHandler = (
locale: Locale,
key: Path,
uid?: number,
type?: string
) => string | void
const i18n = createI18n({
missing: (locale, key, uid, type) => {
// uid is now passed directly as a number
console.warn(`Missing: ${key}`, uid)
}
})Migration
Replace instance parameter with uid:
const i18n = createI18n({
- missing: (locale, key, instance, type) => {
- console.warn(`Missing key "${key}" in ${locale}`, instance?.uid)
+ missing: (locale, key, uid, type) => {
+ console.warn(`Missing key "${key}" in ${locale}`, uid)
}
})