Migrating Vue 2 i18n to Vue 3 Composition API
Legacy Vue 2 applications relying on this.$t() and this.$i18n global prototype injection fail under Vue 3’s Composition API. The removal of automatic instance mounting results in undefined translation contexts, broken reactive locale switching, and incompatible CI/CD l10n extraction pipelines. This guide provides a production-ready migration path to decouple i18n state from Vue’s prototype chain, leveraging factory-based initialization and composition hooks for strict type safety, async chunking, and tree-shaking compatible ESM imports.
1. Migration Scope & Breaking Change Analysis
The architectural shift from Vue 2 to Vue 3 removes prototype-based plugin injection (Vue.prototype.$i18n), requiring developers to explicitly manage i18n contexts at the component level. Understanding these breaking changes is essential for maintaining scalable Frontend Framework i18n & Component Routing strategies across enterprise applications. Without explicit context binding, legacy global mixins will silently fail during SSR hydration or SPA initialization, causing runtime undefined errors and breaking reactive locale propagation.
2. Factory Initialization & Legacy Mode Deprecation
Replace the legacy new VueI18n() constructor with the createI18n() factory. Target vue-i18n@^9.0.0 and enforce legacy: false in the configuration to disable backward-compatibility shims. This ensures strict composition behavior, enables precise dependency tracking, and optimizes bundle splitting.
// src/i18n/index.ts
import { createI18n } from 'vue-i18n'
import en from './locales/en.json'
import es from './locales/es.json'
export const i18n = createI18n({
legacy: false, // Critical: Disables global prototype injection
locale: 'en',
fallbackLocale: 'en',
fallbackWarn: false, // Suppress console noise during partial translation resolution
messages: {
en,
es
}
})
The plugin registration sequence is strict. app.use(i18n) must execute before app.mount('#app') to prevent uninitialized context errors:
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { i18n } from './i18n'
const app = createApp(App)
app.use(i18n) // MUST precede app.mount()
app.mount('#app')
3. Component-Level Hook Migration & Reactive Binding
Refactor all this.$t('key') invocations to the destructured useI18n() composable inside <script setup>. This shift isolates translation contexts to the component scope, eliminating prototype pollution and enabling precise reactivity.
{{ t('welcome.message') }}
Edge Case Handling: Dynamically loaded components or async route chunks may require explicit scope definition. Use useI18n({ useScope: 'local' }) when component-specific message overrides are necessary. Comprehensive setup patterns, type definitions, and advanced composition strategies are detailed in the Vue I18n Composition API Guide.
4. Pipeline Integration & QA Validation
Update CI/CD l10n extraction scripts to parse <script setup> AST nodes. Legacy regex-based extractors will fail to identify t('key') calls within composition functions. Implement automated key-auditing workflows to detect missing translations post-migration, validate pluralization rules, and ensure ICU message syntax compatibility under the new composition runtime.
Production Debugging & Validation Checklist
Execute the following steps before merging to production:
- Verify Plugin Registration Order: Ensure
app.use(i18n)strictly precedesapp.mount()to prevent uninitialized context errors during hydration. - Audit
<script setup>Blocks: Scan for missinguseI18n()imports. Components previously relying on implicitthis.$tavailability will throwReferenceErrorwithout explicit hook invocation. - Validate Dynamic Locale Switching: Confirm
locale.valueupdates propagate reactively across the component tree without requiring manual$forceUpdate()or$nextTick()workarounds. - Check Fallback Chain Resolution: Explicitly define
fallbackLocaleand setfallbackWarn: falseto suppress console noise during partial translation resolution in staging environments. - Run l10n Extraction Tools: Execute extraction against the new composition syntax to confirm key parity, detect orphaned strings, and validate ICU message format compatibility.