vite-vue-internationalization
v0.9.0
Published
A Vite plugin for typed Vue SFC translations with SFC custom blocks and inline locale chunks
Readme
vite-vue-internationalization
A typed internationalization plugin for Vite that lets Vue SFCs own their translations directly.
VVI is the short name for vite-vue-internationalization.
Documentation
Links
It supports <locale> custom blocks, global dictionaries, Volar type completion, and optional locale-specific chunk output.
<template>
<h1>{{ $locale.sfc.title }}</h1>
<p>{{ $l.sfc.count({ n }) }}</p>
</template>
<script setup lang="ts">
const n = 3;
</script>
<locale locale="ja-JP" lang="yaml">
title: りんご
count: "{n} 個のりんご"
</locale>
<locale locale="en-US" lang="yaml">
title: Apple
count: "one apple | {n} apples"
</locale>Features
- Write translations as YAML or JSON in Vue SFC
<locale>blocks. - Get typed
$localeand$lcompletions in templates and TypeScript. - Read app-wide global dictionaries through the same API.
- Opt into injecting
$localeand$lfor every SFC when global dictionary access is needed outside locale-owning components. - Choose between Vue I18n-compatible syntax (
vue) and ICU message syntax (icu). - Choose either the default
virtualbuild strategy orinline-chunksfor locale-specific output chunks. - Share the same configuration between the Vite plugin and Vue Language Tools / Volar.
Minimal Setup
// vite.config.ts
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
import { vueInternationalization } from 'vite-vue-internationalization';
export default defineConfig({
plugins: [
vueInternationalization(),
vue(),
],
});// tsconfig.json
{
"vueCompilerOptions": {
"plugins": [
{
"name": "vite-vue-internationalization/volar",
"primaryLocale": "ja-JP"
}
]
}
}Set sfcTransform: "all" when SFCs without <locale> blocks or defineInternationalization() still need $locale.env or $l.env global dictionary access:
{
"vueCompilerOptions": {
"plugins": [
{
"name": "vite-vue-internationalization/volar",
"primaryLocale": "ja-JP",
"sfcTransform": "all"
}
]
}
}Vite transform output keeps global env bindings as broad runtime dictionary types to avoid duplicating large global type literals in every transformed SFC. Vue Language Tools / Volar uses detailed global dictionary types by default for editor completion and vue-tsc; set globalType: "runtime" in the Volar plugin config when the global dictionary is too large for type checking.
// src/env.d.ts
/// <reference types="vite-vue-internationalization/virtual" />// src/main.ts
import { createApp } from 'vue';
import { createInternationalization } from 'virtual:vite-vue-internationalization';
import App from './App.vue';
const app = createApp(App);
const internationalization = createInternationalization();
app.use(internationalization);
await internationalization.ready;
app.mount('#app');Inline Chunks
The default virtual strategy keeps locale payloads in virtual modules and lets Vite split them with dynamic import() calls.
Use buildStrategy: "inline-chunks" when you want build-time locale-specific JavaScript chunks. This strategy duplicates localizable chunks per locale and replaces static $locale / $l references with locale-specific string literals, dictionaries, or message formatting expressions.
// vite.config.ts
export default defineConfig({
plugins: [
vueInternationalization({
primaryLocale: 'ja-JP',
buildStrategy: 'inline-chunks',
}),
vue(),
],
});The generated HTML entry script is replaced with a small *.i18n-loader.js file. Existing script attributes such as nonce, crossorigin, and referrerpolicy are preserved. If the original script has integrity, it is replaced with integrity for the generated loader, and the loader verifies the selected locale chunk with modulepreload and per-locale chunk integrity before importing it.
Static references such as $locale.sfc.title and $l.sfc.count({ n }) are fully inlined. Dynamic subtree lookups such as $locale.env.labels[key] keep a runtime lookup against the resolved locale-specific subtree. Missing values fall back to the primary locale, then to the key string.
Documentation Pages
- English:
- Japanese:
Examples
- Vue syntax example on StackBlitz
- ICU syntax example on StackBlitz
examples/cloudflare-worker-ssr: Vue SSR to an HTML string in a Cloudflare Workers-style Vite build.examples/nuxt: Nuxt app using VVI throughvite.pluginsand a Nuxt plugin.
To view the documentation locally:
pnpm docs:dev