React
Translating & Values
useTranslation(ns?) returns { t, ready } — t with t.rich / t.markdown attached. Vanilla equivalents are Stift.scope / Stift.t. Hook contract: Setup & Boot Modes.
Calling t
const { t } = useTranslation('checkout')
t('title') // scoped: bare keys in `checkout`
t('title', { count: 3 }) // values fill {params} and drive select/plural
Multi-namespace scope (first namespace with the key wins) and rendering for a locale without switching are vanilla-side APIs — same semantics, see the Overview snippets.
Keys, param shapes, and locales are literal types once the generator emits stift.gen.d.ts — typos and wrong params are compile errors. A cache miss returns the raw key, records it in store.missingKeys, reports hooks.onError({ code: 'missing-key' }), and kicks a background load so the next read resolves. ICU select/plural/offset work through the default engine. Authoring the messages: Messages & Keys, ICU Select & Plural.
Declared vs undeclared params
- Declared in
params.context(stift.config.ts) → optional at call sites. The app supplies them once — from the user profile viasetParam, per-locale defaults, or a<LocaleScope>— andt()auto-merges them. - Undeclared → always required at the call site. There is no strictness dial.
setParam validates against the declared values; an invalid value is rejected and reported via the runtime hooks.
Grammatical agreement via LocaleScope
import { LocaleScope } from '@secundus-studio/stift-react'
<LocaleScope context={{ gender: 'male' }}>{/* t() auto-merges these */}</LocaleScope>
<LocaleScope context={...}> lexically scopes grammatical-agreement params; an explicit param at a call site always wins. Per-locale defaults (defaults: { all: …, ar: … }) are recomputed whenever the active locale switches and inherit down the dialect chain.
Rich text and markdown
Author tags in the message (ICU Select & Plural), wire components in the UI:
t.rich('rich.demo', { strong: (children) => <strong>{children}</strong>, a: (children) => <a href={url}>{children}</a> })
t.markdown('changelog.entry')
Formatting with useFormatter
useFormatter() returns formatting functions only (locale/direction come from useLocale()): numbers, dates, times, relative time, and lists, all locale-aware. Measurement categories (formatLength, formatMass, …) convert from base units to the active unit: Units.
Next
- Measurement units and pickers → Units
- Declaring params/units in config → stift.config.ts
- Missing-key/param logs in the panel → Devtools