Skip to content

React API

tyndale-react provides the runtime provider, translation hooks, formatting components, and server helpers used by Tyndale apps.

Root provider for plain React apps. It loads locale files, exposes translation state, and powers all hooks and components.

import { TyndaleProvider } from 'tyndale-react';
export function App() {
return (
<TyndaleProvider defaultLocale="en" locale="fr">
<Routes />
</TyndaleProvider>
);
}

Props

  • defaultLocale: string
  • locale?: string
  • basePath?: string — defaults to /_tyndale
  • initialTranslations?: Record<string, string>
  • initialManifest?: Manifest | null
  • onLocaleChange?: (locale: string) => void
  • children: React.ReactNode

If initialTranslations is omitted, the provider fetches {basePath}/{locale}.json and manifest.json in the browser.

React context carrying the current locale, manifest, loaded translations, loading state, and changeLocale() function.

Use it directly only when you need custom context access. Most apps should prefer the hooks below.

Reads TyndaleContext and throws if no provider is mounted.

import { useTyndaleContext } from 'tyndale-react';
function LocaleBadge() {
const { locale, defaultLocale, isLoading } = useTyndaleContext();
return <span>{isLoading ? 'Loading…' : `${locale} / ${defaultLocale}`}</span>;
}

Returns a translation function with interpolation support.

import { useTranslation } from 'tyndale-react';
function Greeting({ name }: { name: string }) {
const t = useTranslation();
return <p>{t('Hello, {name}!', { name })}</p>;
}

Signature:

(source: string, vars?: Record<string, string | number>) => string

Returns the current locale string.

import { useLocale } from 'tyndale-react';
const locale = useLocale();

Outside a provider it returns an empty string and logs a warning in development.

Returns a function that changes the active locale.

import { useChangeLocale } from 'tyndale-react';
function LocaleSwitcher() {
const changeLocale = useChangeLocale();
return <button onClick={() => changeLocale('es')}>Español</button>;
}

In plain React, this fetches the new locale JSON and updates provider state. In tyndale-next, the same hook triggers a route change instead.

Returns dictionary entries for a dictionary file as a plain object.

import { useDictionary } from 'tyndale-react';
function Nav() {
const labels = useDictionary('common');
return <a href="/docs">{labels.docs}</a>;
}

Signature:

(filenameKey: string) => Record<string, string>

The hook looks up manifest entries with type: 'dictionary' and falls back to the dictionary key when a translation is missing.

Async server helper that loads a locale file from disk and returns a translation function.

Available from both tyndale-react and the server-only subpath:

import { getTranslation } from 'tyndale-react/server';
const t = await getTranslation({
locale: 'fr',
defaultLocale: 'en',
outputPath: 'public/_tyndale',
});
const title = t('Welcome, {name}!', { name: 'Ada' });

Options:

  • locale: string
  • defaultLocale?: string
  • outputPath: string

If locale === defaultLocale, it skips file loading and returns the source string with interpolation applied.

Marks a literal string for extraction outside component render and returns a React element that resolves at render time.

import { msg } from 'tyndale-react';
const nav = [{ href: '/', label: msg('Home') }];

Marks a literal string for extraction and returns a plain string instead of a React element.

import { msgString } from 'tyndale-react';
export const copy = {
docs: msgString('Documentation'),
};

Use msgString() in non-React contexts such as plain TypeScript modules, Astro frontmatter, or server utilities.

Translates JSX content by serializing its children, looking up the translated wire format, and rendering the translated result.

import { T, Var } from 'tyndale-react';
<T>
Hello, <Var name="name">{name}</Var>!
</T>

If no translation is available, it renders the source children.

Marks a dynamic value inside <T>.

import { T, Var } from 'tyndale-react';
<T>
Hello, <Var name="name">{name}</Var>!
</T>

Formats a number with Intl.NumberFormat. Inside <T>, it also acts as a named placeholder.

import { T, Num } from 'tyndale-react';
<T>
You have <Num name="count" value={count} /> unread messages.
</T>

Formats currency with the active locale.

import { Currency } from 'tyndale-react';
<Currency value={49.99} currency="USD" />

Formats a date or timestamp with Intl.DateTimeFormat.

import { DateTime } from 'tyndale-react';
<DateTime value={new Date()} options={{ dateStyle: 'long' }} />

Selects the correct plural branch for the active locale. Inside <T>, it is serialized to ICU plural syntax.

import { Plural } from 'tyndale-react';
<Plural count={count} one="1 item" other="{count} items" />

These are public exports, but most apps do not need them unless you are integrating with extraction output or wire-format internals.

Compute the normalized SHA-256 hash Tyndale uses for translation lookup.

import { computeHash } from 'tyndale-react';
const id = computeHash('Welcome to our app.');

escapeWireFormat(text) / unescapeWireFormat(text)

Section titled “escapeWireFormat(text) / unescapeWireFormat(text)”

Escape or restore literal text for Tyndale wire format.

serializeChildren(children) / deserializeWireFormat(...)

Section titled “serializeChildren(children) / deserializeWireFormat(...)”

Convert React children to Tyndale wire format and back.

Parse an ICU plural block into its variable name and branches.

Reach for these only when you are building tooling or advanced runtime integrations around Tyndale’s serialized translation format.