Skip to content
fluenti

@fluenti/solid

Provide i18n context to the component tree.

import { I18nProvider } from '@fluenti/solid'
import en from './locales/compiled/en'
import zhCN from './locales/compiled/zh-CN'
<I18nProvider
locale="en"
fallbackLocale="en"
messages={{ en, 'zh-CN': zhCN }}
>
<App />
</I18nProvider>
PropTypeDescription
localestringInitial locale
fallbackLocalestring?Fallback locale
messagesAllMessagesCompiled message catalogs (from fluenti compile)
missing(locale, id) => string?Missing message handler
dateFormatsDateFormatOptions?Custom date format presets
numberFormatsNumberFormatOptions?Custom number format presets
fallbackChainRecord<string, string[]>?Locale fallback chains
lazyLocaleLoadingboolean?Enable async locale loading through chunkLoader
chunkLoader(locale) => Promise<Messages>?Async locale loader

Access the i18n context from the nearest provider.

Use useI18n() when you need the full runtime API (d, n, locale, setLocale, te, tm, etc.). For translation-only code, prefer import { t } instead.

import { useI18n } from '@fluenti/solid'
function MyComponent() {
const { t, format, locale, setLocale, d, n, isLoading, preloadLocale } = useI18n()
return <p>{t('Hello, {name}!', { name: 'World' })}</p>
}
PropertyTypeDescription
t(id, values?) => stringTranslate a message. Also usable as a tagged template: t`Hello ${name}`
format(message, values?) => stringDirect ICU interpolation without catalog lookup
localeAccessor<string>Current locale (signal)
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
isLoadingAccessor<boolean>Whether a locale chunk is loading
loadedLocalesAccessor<Set<string>>Set of loaded locales
preloadLocale(locale) => voidPreload a locale without switching
te(key, locale?) => booleanCheck if a translation key exists in the catalog
tm(key, locale?) => CompiledMessage | undefinedGet the raw compiled message without interpolation

import { t } from '@fluenti/solid' is the primary compile-time translation API.

import { t } from '@fluenti/solid'
function Greeting(props: { name: () => string }) {
return <p>{t`Hello ${props.name()}`}</p>
}

Supported forms:

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

For runtime lookup, imperative access, or ID-based translation, 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.

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

function MyComponent() {
const { format } = useI18n()
return <p>{format('Hello {name}!', { name: 'World' })}</p>
}

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

function PremiumBadge() {
const { te, t } = useI18n()
return te('premium.badge') ? <span>{t('premium.badge')}</span> : null
}
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.

function DebugMessage(props: { id: string }) {
const { tm } = useI18n()
const raw = tm(props.id) // string or compiled function, or undefined
return <pre>{typeof raw === 'function' ? '[dynamic]' : raw ?? '[missing]'}</pre>
}
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.

Rich text with component interpolation. Import it from @fluenti/solid.

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

<Trans>Click <a href="/next">here</a> to continue.</Trans>

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

Pluralization component. Import it from @fluenti/solid.

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.

Select component for gender, role, etc. Import it from @fluenti/solid.

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 props, and the component performs catalog lookup through a synthetic ICU select message at runtime.

Direct-import t is optimized at build time:

import { t } from '@fluenti/solid'
function Greeting() {
const name = 'World'
return <p>{t`Hello ${name}`}</p>
}

Date formatting component.

import { DateTime } from '@fluenti/solid'
<DateTime value={new Date()} format="long" />
PropTypeDescription
valueDate | number(required) Date value to format
stylestring?Named format style (e.g. 'short', 'long', 'relative')

Number formatting component.

import { NumberFormat } from '@fluenti/solid'
<NumberFormat value={1234.56} format="currency" />
PropTypeDescription
valuenumber(required) Number value to format
stylestring?Named format style (e.g. 'currency', 'percent', 'decimal')

@fluenti/solid/components remains available when you want an explicit runtime-only component entry.

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

import { msg } from '@fluenti/solid'
const ROLES = {
admin: msg`Administrator`,
user: msg`Regular User`,
}
// Resolve at render time:
function RoleBadge(props: { role: string }) {
const { t } = useI18n()
return <span>{t(ROLES[props.role])}</span>
}

Low-level factory that creates the i18n context object used internally by I18nProvider. Useful for advanced scenarios like testing, SSR without components, or custom context management.

import { createFluenti } from '@fluenti/solid'
const ctx = createFluenti({
locale: 'en',
messages: { en: compiledMessages },
})
// Access the same API as useI18n()
const translated = ctx.t`Hello`

Returns a FluentiContext with the same shape as useI18n().

When you call t inside a JSX expression, the transformed runtime lookup reads locale() and Solid tracks that reactive scope for you. Direct-import t does not return a memo wrapper by itself.