Vite Plugin
Verified against
@comvi/vite-plugin@0.3.0
@comvi/vite-plugin watches your local translation JSON files during vite dev and generates a TypeScript declaration that types every t() call in your project. It runs fully in-process — no API key, no network, no external service.
Use @comvi/vite-plugin when your translations live as local JSON files and you want autocomplete and parameter validation in your editor.
Use @comvi/cli typegen when your translations live in the Comvi TMS and you want to sync them to your repo or generate types from the live platform schema. See the CLI typegen docs.
Install
Section titled “Install”npm install -D @comvi/vite-plugin# pnpmpnpm add -D @comvi/vite-pluginPeer dependency: vite ^5 || ^6 || ^7 || ^8.
Quick Start
Section titled “Quick Start”import { defineConfig } from "vite";import { comviTypes } from "@comvi/vite-plugin";
export default defineConfig({ plugins: [ comviTypes({ translations: "./src/locales", output: "./src/types/i18n.d.ts", }), ],});The plugin runs once on buildStart and re-runs whenever you save a JSON file inside ./src/locales. The generated declaration is written to ./src/types/i18n.d.ts — make sure that path is covered by tsconfig.json’s include (most src/**/* setups already cover it).
Options
Section titled “Options”interface ComviTypesOptions { translations: string; output?: string; fileTemplate?: string; defaultNs?: string; strictParams?: boolean;}translations
Section titled “translations”Required. Path to the directory containing your translation JSON files, relative to the project root.
comviTypes({ translations: "./src/locales" })output
Section titled “output”Path where the generated .d.ts file is written. Defaults to "./src/types/i18n.d.ts".
fileTemplate
Section titled “fileTemplate”Pattern for matching translation files. Use {languageTag} and {namespace} placeholders.
// Default: one file per namespace per language// matches: common/en.json, admin/de.json, etc.comviTypes({ translations: "./src/locales", fileTemplate: "{namespace}/{languageTag}.json",})For flat single-file-per-language layouts (en.json, de.json), omit fileTemplate — unmatched files are treated as the default namespace.
defaultNs
Section titled “defaultNs”The namespace whose keys appear without a prefix in generated types. Defaults to "default". Set this to match your createI18n({ defaultNs }) value.
comviTypes({ translations: "./src/locales", defaultNs: "common", // keys from common.json → 'welcome', not 'common:welcome'})strictParams
Section titled “strictParams”Whether interpolation parameters are required (true) or optional (false). Defaults to true.
What Gets Generated
Section titled “What Gets Generated”Given this file layout:
src/locales/├── en/│ ├── common.json│ └── errors.json└── de/ ├── common.json └── errors.jsonWith en/common.json:
{ "welcome": "Hello, {name}!", "items": "{count, plural, one {# item} other {# items}}", "greeting": "Hi"}And vite.config.ts:
comviTypes({ translations: "./src/locales", defaultNs: "common",})The plugin writes:
// src/types/i18n.d.ts — DO NOT EDITimport '@comvi/core';
declare module '@comvi/core' { interface TranslationKeys { 'welcome': { name: string }; 'items': { count: number }; 'greeting': never; 'errors:NOT_FOUND': never; }}
export {};Every t() call is now strictly typed:
t("welcome", { name: "Alice" }); // ✓ required param, type-checkedt("greeting"); // ✓ no params neededt("NOT_FOUND", { ns: "errors" }); // ✓ namespaced key
t("welcome"); // ✗ Error: name is requiredt("welcome", { name: 42 }); // ✗ Error: number not assignable to stringt("typo"); // ✗ Error: unknown keyHow Types Plug into Comvi i18n
Section titled “How Types Plug into Comvi i18n”The generated file augments @comvi/core’s TranslationKeys interface via TypeScript declaration merging. No runtime code is shipped — the plugin only writes a .d.ts file. For a full explanation of how type safety works across all methods and frameworks, see Type Safety.
Dev vs Build Behaviour
Section titled “Dev vs Build Behaviour”| Mode | Behaviour |
|---|---|
vite dev | Generates on startup, then re-generates on every JSON add/change/delete inside translations. No server restart needed. |
vite build | Generates once before bundling. A generation error fails the build (unlike dev, which only logs). |
See Also
Section titled “See Also”- Type Safety — how
TranslationKeysaugmentation works,InferKeys, and manual type approaches - CLI typegen — generate types from the Comvi TMS (remote schema, requires API key)