> ## Documentation Index
> Fetch the complete documentation index at: https://docs.suprsend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-lingual Templates

> Deliver notifications in each recipient's preferred language using translation keys or language variants.

SuprSend supports two ways to localise notification templates. The right approach depends on what changes between languages.

| Approach                                                    | Use when                                                                                                   | How it works                                                                                                                                               |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[Translations](#translations-recommended)** (recommended) | The text changes per language, but the template structure (layout, images, buttons) stays the same.        | Use translation keys (`{{t "key"}}`) in your template. SuprSend resolves the key to the user's language at send time from your uploaded translation files. |
| **[Language variants](#language-variants)**                 | The entire content differs per language - different images, layouts, buttons, or structure. Not just text. | Create a separate variant per language with a `locale` condition. Each variant has its own full content.                                                   |

For most use cases, **Translations** is the right choice. It's simpler, easier to maintain, and scales better. Use variants only when you genuinely need different content structure per language.

***

## Setting the user's language

Before either approach works, each user needs a locale set on their profile. Use any backend SDK or the API:

* [Python SDK](/docs/python-create-user-profile#set-preferred-language)
* [Node.js SDK](/docs/node-create-user-profile#set-preferred-language)
* [REST API](/reference/edit-user-profile) - set the `$locale` property

The value should be a standard locale code: `en`, `es`, `fr`, `hi`, `de`, `pt-BR`, etc.

***

## Translations (recommended)

Translations let you keep **one template** and manage all language text in separate JSON files. The template uses **translation keys** instead of raw text - at send time, SuprSend looks up the key in the user's language file and renders the translated text.

### How it works

1. **Upload translation files** — JSON files with key-value pairs, one per language (for example, `en.json`, `es.json`, `fr.json`). Upload from the [dashboard](https://app.suprsend.com/en/staging/developers/translations), [CLI](/reference/cli-translation-overview), or [API](/reference/add-translation).

2. **Use translation keys in your template** - instead of writing raw text, use the `t` helper:

<CodeGroup>
  ```handlebars Handlebars (Email, SMS, Push, Inbox) theme={"system"}
  {{t "order_shipped" order_id=order_id}}
  ```

  ```jsonnet JSONNET (Slack, MS Teams) theme={"system"}
  t("order_shipped", {order_id: data.order_id})
  ```
</CodeGroup>

3. **SuprSend resolves at send time** - reads the user's locale, finds the matching translation file, and renders the translated text with interpolated variables.

### Example

Translation files:

```json en.json theme={"system"}
{
  "order_shipped": "Your order #{{order_id}} has been shipped!",
  "track_button": "Track Order"
}
```

```json es.json theme={"system"}
{
  "order_shipped": "Tu pedido #{{order_id}} ha sido enviado!",
  "track_button": "Rastrear Pedido"
}
```

Template (same for all languages):

```handlebars theme={"system"}
{{t "order_shipped" order_id=order_id}}
```

A user with locale `es` receives: *"Tu pedido #ORD-1234 ha sido enviado!"*

### Fallback logic

If the user's locale file or key is missing, SuprSend falls back:

1. Exact locale (for example, `es-MX.json`)
2. General language (for example, `es.json`)
3. Default language (`en.json`)

Always maintain an `en.json` as the base fallback.

### When to use Translations

* The template layout, images, and buttons are the same across languages - only the text differs.
* You want a single template to serve all languages without creating variants.
* You're scaling to many languages and don't want to maintain separate content per language.
* You want to manage translations outside the template editor (via files, CLI, or API).

For the full reference - managing translation files, pluralization, namespaces, interpolation, and version history - see [Translations](/docs/translations).

***

## Language variants

For cases where the **entire content differs per language** - not just text, but different images, layouts, buttons, or structure - use language variants.

### When to use variants instead of translations

* The email design is structurally different per language (for example, RTL layout for Arabic, different images for Japanese market).
* A specific language version needs completely different content (not just a translation of the same message).
* You want to visually author each language version separately in the editor.

### How to create a language variant

1. Open the template editor, click **+** in the Variants panel, and select **New Variant**.
2. Set the **Locale** to the target language (for example, Spanish).
3. Give it a descriptive **ID** (for example, `default-es`).
4. Author the content for that language. Use [Import content](/docs/templates#import-content) to copy the default English variant as a starting point.
5. Commit.

At send time, SuprSend checks the recipient's locale and sends the matching language variant. If no match, the **default** variant (English) is sent.

<Tip>
  **AI prompt - translate a template:** *"Translate this notification into \[language]. Channel: \[email/SMS/push/WhatsApp]. Content: \[paste]. Preserve all Handlebars variables exactly as-is. Adapt tone for the locale. Flag anything needing cultural adaptation (dates, currency, idioms). Stay within character limits."*
</Tip>

### Combining language with tenant

For tenants that need both brand customisation and localisation, create variants with combined conditions — for example, locale `es` + tenant `acme` for Acme's Spanish-speaking users.

The fallback order: tenant+locale → tenant+default locale → default tenant+locale → default.

Name these descriptively: `acme-es`, `uber-fr`, `default-hi`.

***

## Which approach should I use?

<AccordionGroup>
  <Accordion title="My notifications are the same structure in every language, just different text">
    Use **Translations**. Create translation files per language and use `t` keys in your template. One template, zero variants.
  </Accordion>

  <Accordion title="My email has different images, layout, or buttons per language">
    Use **Language variants**. Create a variant per language with its own full content.
  </Accordion>

  <Accordion title="Can I use both in the same template?">
    Yes. You can use translation keys inside a variant. For example, a tenant-specific variant for Acme could still use `t` keys for localised text - so Acme's Spanish users get both Acme branding and Spanish text without creating `acme-es` as a separate variant.
  </Accordion>

  <Accordion title="I'm scaling to 10+ languages. Which is easier to maintain?">
    Translations, by far. With variants, you'd need to maintain 10+ content versions per channel per template. With translations, you maintain one template and 10 JSON files that can be managed via CLI or API.
  </Accordion>
</AccordionGroup>
