Translating a string
The translate function is the workhorse. Get it from useLocalize():
import { useLocalize } from 'localize-react';
const { translate } = useLocalize();
Signature​
translate(
descriptor: string,
values?: Record<string, string | number>,
defaultMessage?: string,
): string;
| Argument | Required | Purpose |
|---|---|---|
descriptor | ✅ | The key to resolve. Dot-notation walks the tree: 'cart.summary' → translations.cart.summary. |
values | optional | {{placeholder}} substitutions. |
defaultMessage | optional | Fallback rendered when the descriptor isn't found. If omitted, the descriptor itself is returned. |
Resolution algorithm​
- Look up
descriptordirectly in the active translation map. Match? Return it (with interpolation). - If the descriptor contains
., walk segments through the nested tree. - If nothing resolves, render
defaultMessageif given (with interpolation), else the raw descriptor.
translate('cart.summary', { count: 3, total: '$42' });
// → "3 items, $42 total"
translate('cart.unknown.key', undefined, 'Coming soon');
// → "Coming soon"
translate('cart.unknown.key');
// → "cart.unknown.key" (defensive: never throws)
Calling without a provider​
useLocalize() works even with no provider in the tree. You get a passthrough translate that returns defaultMessage ?? descriptor:
function Subscribe() {
// Works without any provider mounted above us.
const { translate } = useLocalize();
return <button>{translate('cta.subscribe', undefined, 'Subscribe')}</button>;
}
That makes the library safe to use in shared components — they degrade to English fallbacks if a consumer forgets to mount the provider.
Composing with formatters​
translate only does string templates. For numbers, dates, and currencies, pre-format with Intl.*:
const fmt = new Intl.NumberFormat(locale, {
style: 'currency',
currency: 'USD',
});
translate('cart.summary', { count: 3, total: fmt.format(42) });
// → "3 items, $42.00 total"
See the Intl formatters recipe for plurals, relative time, and lists.