---
id: react/api/use-translation
title: useTranslation
---

The hook every component uses to read messages. Scoped to a namespace, bound to the active locale, reactive to switches.

```tsx
useTranslation()
useTranslation(ns?: string | string[])
useTranslation(ns, opts?: { suspense?: boolean })
```

## `ns` argument

- Type: `string | string[]`
- Optional — omit it for the unscoped form, where the namespace travels with each call instead.

## `opts.suspense` option

- Type: `boolean`
- Optional — `default: true`
- With `false`, the hook returns `{ t, ready }` and never suspends; gate on `ready` to render fallback UI while packs load. Keep `true` (and a `<Suspense>` boundary) unless a component must mount before its messages arrive.

## Returns

Always `{ t, ready }`. `ready` is `true` once the bound namespaces are loaded for the active locale.

`t` comes in three call styles, all reactive to locale switches:

```tsx
const { t } = useTranslation('common')
t('greeting', { name: user.name })   // scoped: bare keys
t('common', 'greeting')              // unscoped: namespace first — never `t('common.greeting')`
```

`t.rich(key, params)` substitutes components and dates into rich-text messages; `t.markdown(key, { locale }?)` renders a Markdown message (key and locale only — no message params). Keys, param shapes, and locales are literal types once the typegen runs, so typos are compile errors.

## Examples

```tsx
function Greeting({ user }: { user: { name: string } }) {
  const { t, ready } = useTranslation('common', { suspense: false })
  if (!ready) return <Skeleton />
  return <h1>{t('greeting', { name: user.name })}</h1>
}
```

## Next

- Message shapes and ICU select/plural → [Translating & Values](../translating.md)
- Supplying grammatical-agreement context → [`LocaleScope`](./components.md)
- The headless equivalents → [Translating (vanilla)](../../vanilla/api/translate.md)
