Vite Plugins
Vite plugin — Translation completeness check
Checks all locale JSON files against a reference locale and reports any missing or extra keys. Runs at buildStart and on every locale file save during development (HMR).
// vite.config.ts
import { vueI18nCheckPlugin } from 'vue-i18n-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueI18nCheckPlugin({
localesDir: 'src/locales',
defaultLocale: 'en',
failOnMissing: true,
}),
],
})Options
| Option | Type | Default | Description |
|---|---|---|---|
localesDir | string | 'src/locales' | Directory containing locale JSON files, relative to Vite project root. |
defaultLocale | string | first file alphabetically | Locale used as the reference when comparing keys. |
failOnMissing | boolean | false | When true, missing keys abort the build with an error. |
Example output
[vue-i18n-kit] Incomplete translations detected (reference: "en"):
Locale "ru":
Missing keys (2):
- buttons.cancel
- profile.title
Locale "de":
Missing keys (1):
- profile.title
Extra keys (1):
+ legacy.old_keyVite plugin — Inline translations
vueI18nInlinePlugin bakes all locale JSON files into the production bundle at build time via a virtual module. There are no runtime HTTP requests — the translations are a plain JavaScript object embedded in the bundle.
Ideal for: SSR apps, offline-capable PWAs, small projects where bundle size matters less than loading latency.
// vite.config.ts
import { vueI18nInlinePlugin } from 'vue-i18n-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueI18nInlinePlugin({
locales: {
en: 'src/locales/en.json',
ru: 'src/locales/ru.json',
de: 'src/locales/de.json',
},
}),
],
})Usage in your app
import inlineLocales from 'virtual:vue-i18n-kit/locales'
app.use(
createVueI18nPlugin({
defaultLocale: 'en',
locales: {
en: { messages: inlineLocales.en, meta: { display: 'English' } },
ru: { messages: inlineLocales.ru, meta: { display: 'Русский' } },
},
}),
)TypeScript — add to env.d.ts or vite-env.d.ts:
declare module 'virtual:vue-i18n-kit/locales' {
const locales: Record<string, Record<string, unknown>>
export default locales
}Vite plugin — Namespace code splitting
vueI18nNamespacePlugin scans a directory of split locale files and generates the virtual module virtual:vue-i18n-namespaces. The module exports a locales object ready to pass to createVueI18nPlugin — each locale entry includes per-namespace dynamic import() calls so Vite code-splits them automatically.
// vite.config.ts
import { vueI18nNamespacePlugin } from 'vue-i18n-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueI18nNamespacePlugin({
dir: 'src/locales/split',
locales: {
en: { meta: { display: 'English', flag: '🇬🇧' }, eagerNamespaces: ['common'] },
ru: { meta: { display: 'Русский', flag: '🇷🇺' }, eagerNamespaces: ['common'] },
},
}),
],
})Usage in your app
import { locales } from 'virtual:vue-i18n-namespaces'
app.use(createVueI18nPlugin({ defaultLocale: 'en', locales }))Namespaces not in eagerNamespaces are loaded lazily with useNamespace():
const { isLoading } = useNamespace('dashboard')
// or several at once:
const { isLoading } = useNamespace(['dashboard', 'charts'])Options
| Option | Type | Default | Description |
|---|---|---|---|
dir | string | 'src/locales/split' | Directory containing locale subdirectories (<dir>/<locale>/<namespace>.json). |
locales | Record<string, { meta?, eagerNamespaces? }> | {} | Per-locale config. Locales found in the directory but not listed here are included automatically. |
HMR: when any namespace JSON file inside dir changes, Vite invalidates and reloads the virtual module automatically.
Vite plugin — In-context translation editor (dev only)
vueI18nDevPlugin injects a floating editor overlay into your running application during development. Translated strings can be wrapped with the <I18nInspect> component to show a pencil icon on hover; clicking it opens an inline popup for editing that key.
The plugin is a complete no-op during production builds.
// vite.config.ts
import { vueI18nDevPlugin } from 'vue-i18n-kit/vite'
export default defineConfig({
plugins: [
vue(),
vueI18nDevPlugin(), // uiUrl is set automatically by vue-i18n-kit dev
],
})Start both servers with one command:
npx vue-i18n-kit devThis auto-detects scripts.dev from package.json, starts both Vite and the locale editor UI in parallel, and passes I18N_KIT_UI_URL to vueI18nDevPlugin automatically.
Auto-wrap (default)
By default vueI18nDevPlugin automatically rewrites Vue SFC templates at dev time. Every {{ t('key') }}, {{ tm('key') }}, and {{ $t('key') }} interpolation is wrapped with <I18nInspect> — no manual markup needed.
<!-- Source as written -->
<template>
<p>{{ t('nav.home') }}</p>
</template>
<!-- What Vite actually compiles in dev mode -->
<template>
<p>
<I18nInspect i18n-key="nav.home">{{ t('nav.home') }}</I18nInspect>
</p>
</template>Set autoWrap: false to use explicit <I18nInspect i18n-key="…"> markup or the v-i18n-inspect directive instead.
Dynamic keys — v-i18n-inspect directive
For runtime keys (variables, computed values, loop indices) use the directive which attaches hover behaviour to the existing element without adding a wrapper node:
<span v-i18n-inspect="activeKey">{{ t(activeKey) }}</span>
<span v-i18n-inspect="`items.${item.id}`">{{ t(`items.${item.id}`) }}</span>Options
| Option | Type | Default | Description |
|---|---|---|---|
uiUrl | string | I18N_KIT_UI_URL env or 'http://localhost:4173' | URL of the running vue-i18n-kit ui server. |
autoWrap | boolean | true | Automatically wrap t() / tm() / $t() interpolations with <I18nInspect> at dev time. |
wrapFunctions | string[] | ['t', 'tm', '$t'] | Function names to look for when autoWrap is enabled. |
iframeWidth | string | '480px' | Width of the right-side iframe editor panel. |