Plugin Setup
Plugin options
interface I18nPluginOptions {
defaultLocale: string
fallbackLocale?: string
locales: Record<string, LocaleEntry>
persistLocale?: boolean
storageKey?: string
vueI18nOptions?: Record<string, unknown>
}defaultLocale
string, required. Locale loaded on startup.
fallbackLocale
string, optional. Locale used when a key is missing in the active locale. Also pre-loaded synchronously so it is available immediately.
locales
Record<string, LocaleEntry>, required. Map of locale codes to message objects, loader functions, or LocaleDefinition objects. See formats below.
persistLocale
boolean · default: false. Save the selected locale to localStorage and restore it on next visit. See Locale persistence below.
storageKey
string · default: 'vue3-i18n-locale'. Key used for localStorage when persistLocale is true.
vueI18nOptions
object, optional. Extra options forwarded directly to vue-i18n's createI18n.
Locale entry formats
Each locale in the locales map accepts one of three forms. They can be freely mixed within the same config.
1. Plain message object (synchronous)
locales: {
en: { buttons: { submit: 'Submit' }, greeting: 'Hello, {name}!' },
}Messages are bundled into the app at build time and available immediately.
2. Async loader function (lazy)
locales: {
ru: () => import('./locales/ru.json'),
}The JSON file is fetched only when setLocale('ru') is called. Until then it has zero impact on the initial bundle size.
3. LocaleDefinition — messages + custom metadata
locales: {
en: {
messages: () => import('./locales/en.json'),
meta: { display: 'English', flag: '🇬🇧' },
},
ru: {
messages: () => import('./locales/ru.json'),
meta: { display: 'Русский', flag: '🇷🇺', author: 'Danil Lisin' },
},
}meta is an arbitrary object — the shape is entirely up to the project. It is accessible through useLocale().localeMeta and useAvailableLocales().availableLocales[n].meta. All three forms can be mixed freely in the same locales map.
Locale persistence
When persistLocale: true is set, the selected locale is saved to localStorage under the configured storageKey. On the next page load the plugin reads this value and uses it as the initial locale, falling back to defaultLocale if the saved value is not a registered locale code.
localStorage calls are wrapped in try/catch so the plugin works without issues in environments where storage is restricted (private browsing, certain iframe contexts).
persistLocale vs manual localStorage
- Setup —
persistLocale: true: one option increateVueI18nPlugin. Manual: read on startup, write inonLocaleChange. - Restore on page load —
persistLocale: true: automatic. Manual: you read the key and pass the value asdefaultLocale. - Good when —
persistLocale: true: you just need locale to survive a page reload. Manual: you store extra data alongside the locale, usesessionStorage, or share the key with other parts of the app.
Option A — let the plugin handle it (recommended for most projects):
app.use(createVueI18nPlugin({
defaultLocale: 'en',
locales: { ... },
persistLocale: true,
}))Option B — manage storage yourself:
const saved = localStorage.getItem('my-locale')
const initial = ['en', 'ru'].includes(saved ?? '') ? saved! : 'en'
app.use(i18nPlugin) // persistLocale is NOT set
i18nPlugin.service.onLocaleChange((lang) => {
localStorage.setItem('my-locale', lang)
})Do not combine both options for the same storage key. If
persistLocale: trueis set and you also calllocalStorage.setItemmanually, the plugin will overwrite your value on the nextsetLocale.