Skip to content
fluenti

@fluenti/vue

Create a Vue plugin instance. SSR-safe — call once per request in SSR.

import { createFluenti } from '@fluenti/vue'
import en from './locales/compiled/en'
import zhCN from './locales/compiled/zh-CN'
const i18n = createFluenti({
locale: 'en',
fallbackLocale: 'en',
messages: { en, 'zh-CN': zhCN },
})
app.use(i18n)
PropertyTypeDescription
localestringInitial locale
fallbackLocalestring?Fallback locale
messagesAllMessagesCompiled message catalogs (from fluenti compile)
missing(locale, id) => string?Called when a translation key is missing from the catalog
dateFormatsRecord<string, DateTimeFormatOptions | 'relative'>?Named date styles
numberFormatsRecord<string, NumberFormatOptions>?Named number styles
fallbackChainRecord<string, string[]>?Locale fallback chains
lazyLocaleLoadingboolean?Enable async locale loading through chunkLoader
chunkLoader(locale: string) => Promise<Messages>?Async locale loader used when lazyLocaleLoading is enabled
componentPrefixstring?Prefix for global components (e.g. 'I18n'I18nTrans, I18nPlural, I18nSelect)
injectGlobalPropertiesboolean?When false, skips injecting $t, $d, $n, $vtRich onto app.config.globalProperties. Useful when another i18n library (e.g. vue-i18n) already provides $t. Default: true

Composable to access the i18n context.

<script setup>
import { useI18n } from '@fluenti/vue'
const { t, format, locale, setLocale, d, n, isLoading, loadedLocales, preloadLocale } = useI18n()
</script>
PropertyTypeDescription
t(id, values?) => stringTranslate a message
format(message, values?) => stringDirect ICU interpolation without catalog lookup
localeRef<string>Current locale (reactive)
setLocale(locale) => Promise<void>Change locale (async with lazy locale loading)
loadMessages(locale, messages) => voidLoad messages at runtime
getLocales() => string[]Get all loaded locale codes
d(value, style?) => stringFormat a date
n(value, style?) => stringFormat a number
isLoadingRef<boolean>Whether a locale chunk is loading
loadedLocalesRef<ReadonlySet<string>>Set of loaded locales
preloadLocale(locale) => voidPreload a locale without switching

import { t } from '@fluenti/vue' is the primary compile-time translation API for <script setup> and supported setup scopes.

<script setup>
import { t } from '@fluenti/vue'
const pageTitle = t`Welcome to Fluenti`
</script>
<template>
<h1>{{ pageTitle }}</h1>
</template>

Supported forms:

  • t`Hello ${name}`
  • t({ message: 'Hello {name}', context: 'hero' }, { name })

For runtime lookup, locale switching, or reactive script-driven values, use useI18n().t().

Without the Fluenti build plugin, imported t is not available as a runtime fallback. Use useI18n().t() for imperative lookup, while the components below continue to work normally.

TypeScript users can also import the public component prop types directly from @fluenti/vue: FluentiTransProps, FluentiPluralProps, FluentiSelectProps, FluentiDateTimeProps, and FluentiNumberFormatProps.

Direct ICU interpolation without catalog lookup. Useful for one-off messages or dynamic patterns.

<script setup>
import { useI18n } from '@fluenti/vue'
const { format } = useI18n()
</script>
<template>
<p>{{ format('Hello {name}!', { name: 'World' }) }}</p>
</template>

Check whether a translation key exists in the catalog without resolving it.

<script setup>
import { useI18n } from '@fluenti/vue'
const { te } = useI18n()
</script>
<template>
<span v-if="te('premium.badge')">{{ t('premium.badge') }}</span>
</template>
ParameterTypeDescription
keystringMessage ID to check
localestring?Override locale (defaults to current)

Returns: boolean

Retrieve the raw compiled message without interpolation. Useful for inspecting what is in the catalog.

<script setup>
import { useI18n } from '@fluenti/vue'
const { tm } = useI18n()
const raw = tm('greeting') // string or compiled function, or undefined
</script>
ParameterTypeDescription
keystringMessage ID to retrieve
localestring?Override locale (defaults to current)

Returns: CompiledMessage | undefined — a string for static messages, a (values?) => string function for dynamic messages, or undefined if not found.

If Trans, Plural, or Select conflicts with another library (e.g. a UI framework), use componentPrefix:

const i18n = createFluenti({
locale: 'en',
messages: { en },
componentPrefix: 'I18n',
})

Components will be registered as I18nTrans, I18nPlural, I18nSelect:

<template>
<I18nTrans>Visit our <a href="/docs">docs</a></I18nTrans>
<I18nPlural :value="count" one="# item" other="# items" />
<I18nSelect :value="role" :options="{ admin: 'Admin', user: 'User' }" other="Unknown" />
</template>

For Nuxt, set componentPrefix in nuxt.config.ts — it applies to NuxtLinkLocale as well:

export default defineNuxtConfig({
fluenti: {
componentPrefix: 'I18n',
// → I18nNuxtLinkLocale
},
})

Rich text component with slot-based component injection. Globally registered — no import needed.

The default slot is the primary API. The slot content is the source-language message, which is auto-extracted and translated via the catalog:

<Trans>Visit our <a href="/docs">documentation</a> to learn more.</Trans>

Use native HTML elements directly in the slot:

<Trans>Click <a href="/next">here</a> to continue.</Trans>
<Trans>This is <strong>important</strong> information.</Trans>
PropTypeDefaultDescription
idstringOverride the auto-generated message ID
contextstringMessage context used for identity and translator disambiguation
commentstringTranslator-facing comment preserved in extraction output
tagstring'span'Wrapper element

Trans remains runtime-correct without the build plugin. The plugin only removes runtime extraction work.

Shorthand for ICU plural patterns. Globally registered — no import needed.

Plural forms are source-language text, auto-extracted and translated via the catalog:

<Plural :value="count" one="# item" other="# items" />

Plural remains runtime-correct without the build plugin. It performs catalog lookup through a synthetic ICU plural message at runtime.

Shorthand for ICU select patterns. Globally registered — no import needed.

Use the options prop for type-safe select patterns:

<Select :value="gender" :options="{ male: 'He', female: 'She' }" other="They" />

Alternatively, pass options as attributes:

<Select :value="gender" male="He" female="She" other="They" />

Select also remains runtime-correct without the build plugin. options takes precedence over direct case attributes, and the component performs catalog lookup through a synthetic ICU select message at runtime.

Date formatting component. Globally registered — no import needed.

<DateTime :value="new Date()" />
<DateTime :value="Date.now()" format="short" />
<DateTime :value="event.date" format="long" tag="time" />
PropTypeDefaultDescription
valueDate | number(required) Date value to format
stylestringNamed format style (e.g. 'short', 'long', 'relative')
tagstring'span'Wrapper element

Number formatting component. Globally registered — no import needed.

<NumberFormat :value="1234.56" />
<NumberFormat :value="0.75" format="percent" />
<NumberFormat :value="99.99" format="currency" tag="strong" />
PropTypeDefaultDescription
valuenumber(required) Number value to format
stylestringNamed format style (e.g. 'currency', 'percent', 'decimal')
tagstring'span'Wrapper element

Re-exported from @fluenti/core. Create lazy message descriptors for module-level constants.

<script setup>
import { msg } from '@fluenti/vue'
import { useI18n } from '@fluenti/vue'
const ROLES = {
admin: msg`Administrator`,
user: msg`Regular User`,
}
const { t } = useI18n()
</script>
<template>
<span>{{ t(ROLES[role]) }}</span>
</template>