---
id: vanilla/api/translate
title: Translating
---

Everything here is plain `@secundus-studio/stift-core` — the React hooks are thin wrappers over these exact methods. Keys, param shapes, and locales are literal types once the typegen runs, so typos and wrong params are compile errors.

## `stift.t`

```ts
stift.t('checkout', 'title')                              // unscoped: namespace + key
stift.t('checkout', 'title', { count: 3 })                // with params
stift.t('checkout', 'title', { count: 3 }, 'ar')          // render for a locale without switching
stift.getMessage('common', 'rich.demo')                   // raw source string, unformatted
```

Params split two ways: **declared** in `params.context` are optional at call sites (supply once via `setParam`, every call auto-merges them); **undeclared** are always required. There is no strictness dial.

A cache miss returns the raw key, records it, reports `hooks.onError({ code: 'missing-key' })`, and kicks a background load so the next read resolves.

## `stift.scope`

```ts
stift.scope('checkout')('title')              // scoped: bare keys
stift.scope(['common', 'checkout'])('login')  // multi: first namespace with the key wins
```

Binds one namespace (or an ordered list) so call sites use bare keys. The multi form resolves against the first namespace that holds the key.

## `stift.getMessage`

```ts
stift.getMessage(namespace, key, locale?)
```

- Returns the raw message source for a key — the string the formatters parse, before ICU selection or interpolation. Feed it to `parseMessage` to walk the AST yourself (rich-text tags, Markdown); the React `t.rich`/`t.markdown` renderers are thin wrappers over exactly this.

## Examples

```ts
const title = stift.scope('checkout')('title')
const arabic = stift.t('checkout', 'title', { count: 3 }, 'ar-SY')
```

## Next

- Authoring the messages → [Messages & Keys](../../authoring/messages.md)
- Params: declared vs undeclared → [stift.config.ts](../../configuration/config-file.md)
- The React wrappers → [`useTranslation`](../../react/api/use-translation.md)
