Skip to content

Plugin Setup

Plugin options

ts
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)

ts
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)

ts
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

ts
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

  • SetuppersistLocale: true: one option in createVueI18nPlugin. Manual: read on startup, write in onLocaleChange.
  • Restore on page loadpersistLocale: true: automatic. Manual: you read the key and pass the value as defaultLocale.
  • Good whenpersistLocale: true: you just need locale to survive a page reload. Manual: you store extra data alongside the locale, use sessionStorage, or share the key with other parts of the app.

Option A — let the plugin handle it (recommended for most projects):

ts
app.use(createVueI18nPlugin({
  defaultLocale: 'en',
  locales: { ... },
  persistLocale: true,
}))

Option B — manage storage yourself:

ts
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: true is set and you also call localStorage.setItem manually, the plugin will overwrite your value on the next setLocale.