Skip to content
fluenti

How It Works

Source Code → Extract → Catalog → Compile → Bundle
↓ ↓ ↓ ↓ ↓
.vue/.tsx fluenti .po .js module Vite
extract catalog per locale build

The v-t directive is a compile-time nodeTransform, not a runtime directive.

Input: <p v-t>Hello {{ name }}</p>
↓ (Vue compiler nodeTransform)
Output: <p>{{ $t('Hello {{ name }}') }}</p>
Input: const greeting = t`Hello ${name}`
↓ (Vite transform hook)
Output: const greeting = computed(() => __i18n.t('Hello {name}', { name: unref(name) }))

The Vite plugin also auto-injects the necessary imports.

fluenti extract scans source files for all translatable patterns and outputs a catalog:

{
"Hello {name}": {
"message": "Hello {name}",
"origin": { "file": "src/App.vue", "line": 5 }
}
}

fluenti compile converts ICU messages into optimized JavaScript:

/* @__PURE__ */ export const _a1b2c3 = (v) => `Hello ${v.name}`
/* @__PURE__ */ export const _d4e5f6 = 'Welcome to Fluenti'
export default {
'Hello {name}': _a1b2c3,
'Welcome to Fluenti': _d4e5f6,
}

Static messages become plain strings (zero overhead). Dynamic messages become small functions. The @__PURE__ annotations enable tree-shaking — unused messages are eliminated from the production bundle. The export default re-export allows catalog imports by message ID key.

The core uses a hand-written recursive descent parser for ICU MessageFormat. It handles variables, plurals, selects, nested messages, number/date functions, and quote escaping.