# Translate your messages

Start here to learn how to translate messages and send them to the right recipients. Across any workflow, you’ll create your message in a default language then translate it to all language variants you support. You’ll handle translations within message editors and won’t need to create branches in your campaigns to send the right language variant.

## How it works[](#how-it-works)

To localize messages, you’ll follow this process:

1.  [Set a language attribute for your workspace](/journeys/localization-attribute/) so we know how to determine a recipient’s language preference.
2.  Create messages with language variants.

When you add or update people, you can set an [attributeA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/) containing their language preference. Then, when you set up messages, you add translations matching your users’ language attributes.

You can add language variants to any message channel: email, SMS, [Whatsapp](/journeys/send-whatsapp/), push, and in-app.

When your message sends, we match people’s language attribute to your translations. If we don’t find a match, we’ll send them the *Default* message, as indicated at the top of the editor.

## Set up a multi-language message[](#set-up-a-multi-language-message)

[After you define your language attribute](#how-it-works), you can start adding translated content. When you create a message with multiple languages, you begin by drafting your ***Default* message**. People receive the Default message when their language preferences don’t exist or don’t match one of the translation options.

The Default message is also the foundation of each of your translations. If you [leverage our agent to translate your content](/journeys/localization-getting-started/#how-translating-with-ai-works), it translates your Default message.

To create a message and add translations, follow these steps:

1.  Draft your **Default** message.
2.  Click **Add language** and check the languages you’ll want to include. In Design Studio, you need to click next to the email’s name to find this.
    
    [![Language options where French and auto-translate with AI are checked](https://docs.customer.io/images/localization-add-languages.png)](#1192b17725324c9f2aefb5cb6d859fc2-lightbox)
    
3.  Select [**Auto-translate with AI**](#how-translating-with-ai-works) if you want to use our agent. Remember to review the results for accuracy. Otherwise, you can learn more about working with [translation vendors](#best-practices) and how to export/import content below.
4.  Send yourself a test to make sure each version renders as expected.
5.  Save your changes.

## Translate with AI[](#how-translating-with-ai-works)

You can translate your default message with AI when you add a language variant. This is available across all of our message channels. Remember to review your translations for accuracy; generative AI can make mistakes.

[![Language options where french and auto-translate with AI are checked](https://docs.customer.io/images/localization-add-languages.png)](#1192b17725324c9f2aefb5cb6d859fc2-lightbox)

 Not seeing this AI feature?

Make sure “Customer.io AI” is enabled in [Privacy, Data, & AI settings](https://fly.customer.io/settings/privacy). Reach out to an *Account Admin* if you can’t edit the toggle.

### What our AI auto-translates[](#what-our-ai-auto-translates)

The Auto-translate tool will translate the following:

*   Body text
*   Subject lines
*   [Preheader text](/journeys/custom-preheader-text/)

It will not auto-translate the following:

*   Images, but it will translate alt text
*   [Email layouts](/journeys/3-layouts-and-customerio/) in the rich text or code editors
*   [Liquid](#consider-liquid-values): Static text, attribute values, filter values, etc.
*   [Snippets](/journeys/snippets/): Rather, you should add liquid conditionals based on people’s language preferences to the snippet file.
*   Text in [custom components](/journeys/components-overview/#custom-components): However, our AI tool will translate the text if you detach the component first, and then translate the message. Learn more about [detaching a component](/journeys/create-custom-component/#edit-the-component-in-your-email) from its source file.

### Regenerate translations with AI[](#regenerate-translations-with-ai)

We do not automatically update translations when you change the default template.

For most editors, if you made a change to your default message and want translations to reflect the updates, you’ll need to [delete the translations](#delete-a-language) and then re-add the language variants.

#### Sync translations in Design Studio[](#sync-translations-in-design-studio)

In Design Studio, if you made changes to your default message and want translations to reflect the updates, you can refresh your translations from your default message. Unlike other editors, you don’t have to delete and then re-add the variants.

1.  Click the language dropdown, and choose **Refresh from Default**.
2.  Select which languages you want to regenerate from your default template. By default, we’ll auto-translate with AI, but if you uncheck this option, we’ll overwrite the template with the default message.
3.  Click **Refresh selected**. This overwrites your selected language variants with the latest translations.

### Retry failed AI translations[](#retry-failed-ai-translations)

Sometimes a translation fails, like when there’s an issue connecting with our AI service. If a translation fails, you can click **Retry** in the failure notification.

[![The retry button appears if any translation fails](https://docs.customer.io/images/add-language-retry.png)](#fa657df183f024ea409be4c520b8e2c4-lightbox)

### Languages we don’t auto-translate[](#languages-that-wont-be-auto-translated)

This feature can auto-translate most languages we support, but check out the exceptions in our [locale list](#supported-languages).

If you select a locale that is not officially supported by our Auto-translate feature, you’ll see that we won’t translate it:

[![The locales uz and tk are checked. A note says auto-translate is not available for tk.](https://docs.customer.io/images/localization-unsupported-languages.png)](#b8232139b3b9647f964ee4513290f652-lightbox)

In this example, both locales for Turkmen (tk) and Uzbek (uz) are selected, as indicated by the bubbles below the locale list. We will auto-translate Uzbek, but not Turkmen. After you click **Add**, new tabs appear for both languages. However, only Uzbek will show a translation. Turkmen would show a copy of the default message and still need to be translated by another service or vendor. Below are some tips for working with a [translation vendor](#best-practices).

## Translating liquid[](#consider-liquid-values)

When we send your message, we render liquid based on the values stored on attributes, so make sure you store values in native languages. For instance, if you store the most frequent purchase on a person’s profile like `"frequent_purchase":"soap"` and you want to include that in the message, the word “soap” would appear, no matter their language preference.

Whether you’re adding languages with our auto-translate feature or through a vendor, make sure you translate any copy within your liquid statements as well as default filter values. For instance, we don’t auto-translate the fallback in `{{customer.first_name | default:"there"}}`.

To add a simple greeting with a fallback, you’d translate the value in `default`:

```fallback
Bonjour {{ customer.first_name | default:"ami" }}
```

You could also include a single liquid conditional across your language variants so the fallback renders based on a language variable. The text between conditions is not automatically translated:

```fallback
{% if customer.first_name %}
  {{customer.first_name}}
{% elsif customer.language == 'fr' %}
  ami
{% else %}
  there
{% endif %}
```

## How to work with a translation vendor[](#best-practices)

### Export email to HTML for vendors[](#export-import-email)

When you set up a message with multiple languages, you may need to send content to a translation vendor. To simplify this process, we suggest that you draft, test, and finalize your **Default** message first.

We recommend you send HTML to a translation vendor, unless your vendor requests a different format. How you export to HTML depends on the editor you’re using:

*   [Design Studio](/journeys/design-studio-overview/):
    *   If you built the email using our **component syntax** (like `<x-paragraph>`), switch to the code editor, and copy/paste the code into a shareable file.
    *   If you built the email from **standard HTML** (like `<p>`), click next to the email name, select **Export**, then copy/paste the HTML and save it as a file you can share externally.
*   [Drag-and-drop editor](/journeys/email-editors/#drag-and-drop): Click **Actions** > **Export to HTML**.
*   [Rich text editor](/journeys/email-editors/#rich-text): Click **HTML** underneath the email header to copy/paste the source code. Then save this to a file to share externally.
*   [Code editor](/journeys/email-code-editor/): Copy your HTML and save to a separate file.

### Add translations from vendors[](#add-translations-for-email-from-vendors)

To add a translation to your message:

1.  Click **Add language**. In Design Studio, you need to click next to the email’s name to find this.
2.  Select one or more languages to add. Make sure **Auto-translate with AI** is not selected.
3.  Add in your translated content:

 Design Studio

#### Design Studio[](#Design Studio)

*   If you exported the **component syntax** (like `<x-paragraph>`), [switch to the code editor](/journeys/code-editor-overview/#code-your-message), and replace the code with the returned translation.
*   If you exported **standard HTML** (like `<p>`), paste in the translated text.

 Drag-and-drop editor

#### Drag-and-drop editor[](#Drag-and-drop editor)

Paste translated text into the blocks of your message.

 Rich text editor

#### Rich text editor[](#Rich text editor)

Click **HTML** then paste in your translated HTML. You may need to reformat text after pasting.

 Code editor

#### Code editor[](#Code editor)

Paste in the translated HTML.

## A/B tests with localized messages[](#ab-tests-with-localized-messages)

You can A/B test messages with translations in newsletters, but not API-triggered broadcasts or campaigns. If you add languages to a message in a campaign workflow, you can’t A/B test that message—even if you delete the languages later.

To set up A/B tests for newsletters with translations, you’ll follow the [same process as you would without translations](/journeys/newsletters/#testing-newsletter-broadcasts). Just make sure whatever changes you make to each test are duplicated across all language variants. For instance, if you’re testing different subject lines between variant A and B, make sure the subject is translated accordingly.

If you set up languages for each variant in your test, we’ll split users across the tests before we check their language attribute. So, while your audience is split according to your settings, they might not be split evenly across languages variants.

## Right-to-left text formatting[](#rtl-formatting)

When editing emails or in-app messages, you can expand *Advanced* options for paragraphs and other elements that contain text and use the **Text Direction** setting to control for right-to-left or left-to-right text.

[![The text direction setting in the advanced options for a paragraph](https://docs.customer.io/images/right-to-left-settings.png)](#50f2c587e2e0c7759d07ad41f7d5800c-lightbox)

### Mixing LTR and RTL text[](#mixing-ltr-and-rtl-text)

When creating messages that mix right-to-left (RTL) languages like Arabic with left-to-right (LTR) languages like English in our email and in-app message editors, you may need to control the text direction to ensure proper display.

You can control text direction inline using Unicode directional formatting characters:

*   **RLE (Right-to-Left Embedding)**: `&#x202B;` - Place before Arabic text to embed it in a right-to-left context.
*   **PDF (Pop Directional Formatting)**: `&#x202C;` - Place after Arabic text to return to the previous directional context.

```fallback
Welcome to Customer.io! &#x202B;‫مرحبا بك في كستمر.آي.أو‬&#x202C; Let's get started.
```

## Delete a language[](#delete-a-language)

When composing a message, you can remove languages that you add by mistake or delete them to re-add new versions.

1.  Click the tab for the language you want to remove. In Design Studio, this is a dropdown menu.
2.  Click .
3.  Confirm the action.

If some people have this language as their preference, they will receive the default message moving forward.

[![There is a red rectangle around the default tab in the top left of a message editor.](https://docs.customer.io/images/localization-language-tags-default.png)](#c093b8636e0a272a43dcf2bdba437233-lightbox)

## Supported languages and locales[](#supported-languages)

You must format the values of your language attribute as two-letter language codes with an optional two-letter region code separated by a dash, like `en` or `en-US`.

Language attribute values are **not case sensitive**, but language-region codes **must** be separated by a dash. For example, both `es-MX` and `es-mx` represent Spanish formatted for speakers in Mexico.

These codes come from the ISO-3166-1 (alpha 2) and IETF standards respectively. If you’re looking for a language or locale that we don’t support, [let us know](mailto:product@customer.io)!

Any code with an asterisk (\*) is not officially supported by our [auto-translate feature](/journeys/localization-getting-started/#how-translating-with-ai-works). You’ll have to use another service to get an accurate translation.

Code

Language/Locale

af

Afrikaans

af-ZA

Afrikaans (South Africa)

am-ET

Amharic (Ethiopia)

ar

Arabic

ar-AE

Arabic (U.A.E.)

ar-BH

Arabic (Bahrain)

ar-DZ

Arabic (Algeria)

ar-EG

Arabic (Egypt)

ar-IQ

Arabic (Iraq)

ar-JO

Arabic (Jordan)

ar-KW

Arabic (Kuwait)

ar-LB

Arabic (Lebanon)

ar-LY

Arabic (Libya)

ar-MA

Arabic (Morocco)

ar-OM

Arabic (Oman)

ar-QA

Arabic (Qatar)

ar-SA

Arabic (Saudi Arabia)

ar-SY

Arabic (Syria)

ar-TN

Arabic (Tunisia)

ar-YE

Arabic (Yemen)

arn-CL\*

Mapudungun (Chile)

as-IN

Assamese (India)

az

Azeri

az-Cyrl-AZ

Azeri (Cyrillic) (Azerbaijan)

az-Latn-AZ

Azeri (Latin) (Azerbaijan)

ba-RU\*

Bashkir (Russia)

be

Belarusian

be-BY

Belarusian (Belarus)

bg

Bulgarian

bg-BG

Bulgarian (Bulgaria)

bn-BD

Bengali (Bangladesh)

bn-IN

Bengali (India)

bo-CN\*

Tibetan (Peoples Republic of China)

bi\*

Bislama

br-FR\*

Breton (France)

bs-Cyrl-BA

Bosnian (Cyrillic) (Bosnia and Herzegovina)

bs-Latn-BA

Bosnian (Latin) (Bosnia and Herzegovina)

ca

Catalan

ca-ES

Catalan (Catalan)

co-FR

Corsican (France)

cs

Czech

cs-CZ

Czech (Czech Republic)

cy-GB

Welsh (United Kingdom)

da

Danish

da-DK

Danish (Denmark)

de

German

de-AT

German (Austria)

de-CH

German (Switzerland)

de-DE

German (Germany)

de-LI

German (Liechtenstein)

de-LU

German (Luxembourg)

dsb-DE\*

Lower Sorbian (Germany)

dv

Divehi

dv-MV

Divehi (Maldives)

el

Greek

el-GR

Greek (Greece)

en

English

en-029

English (Caribbean)

en-AT

English (Austria)

en-AU

English (Australia)

en-BE

English (Belgium)

en-BZ

English (Belize)

en-CA

English (Canada)

en-DE

English (Germany)

en-ES

English (Spain)

en-FR

English (France)

en-GB

English (United Kingdom)

en-GH

English (Ghana)

en-IE

English (Ireland)

en-IN

English (India)

en-JM

English (Jamaica)

en-LU

English (Luxembourg)

en-MY

English (Malaysia)

en-NL

English (Netherlands)

en-NZ

English (New Zealand)

en-PH

English (Republic of the Philippines)

en-SG

English (Singapore)

en-TT

English (Trinidad and Tobago)

en-US

English (United States)

en-ZA

English (South Africa)

en-ZW

English (Zimbabwe)

es

Spanish

es-AR

Spanish (Argentina)

es-BO

Spanish (Bolivia)

es-CL

Spanish (Chile)

es-CO

Spanish (Colombia)

es-CR

Spanish (Costa Rica)

es-DO

Spanish (Dominican Republic)

es-EC

Spanish (Ecuador)

es-ES

Spanish (Spain)

es-GT

Spanish (Guatemala)

es-HN

Spanish (Honduras)

es-LA

Spanish (Latin America)

es-MX

Spanish (Mexico)

es-NI

Spanish (Nicaragua)

es-PA

Spanish (Panama)

es-PE

Spanish (Peru)

es-PR

Spanish (Puerto Rico)

es-PY

Spanish (Paraguay)

es-SV

Spanish (El Salvador)

es-US

Spanish (United States)

es-UY

Spanish (Uruguay)

es-VE

Spanish (Venezuela)

et

Estonian

et-EE

Estonian (Estonia)

eu

Basque

eu-ES

Basque (Basque)

fa

Persian

fa-IR

Persian (Iran)

fi

Finnish

fi-FI

Finnish (Finland)

fil-PH

Filipino (Philippines)

fo\*

Faroese

fo-FO\*

Faroese (Faroe Islands)

fr

French

fr-BE

French (Belgium)

fr-CA

French (Canada)

fr-CH

French (Switzerland)

fr-FR

French (France)

fr-LU

French (Luxembourg)

fr-MC

French (Principality of Monaco)

fy-NL

Frisian (Netherlands)

ga-IE

Irish (Ireland)

gd-GB

Scottish Gaelic (United Kingdom)

gl

Galician

gl-ES

Galician (Galician)

gsw-FR\*

Alsatian (France)

gu

Gujarati

gu-IN

Gujarati (India)

ha-Latn-NG

Hausa (Latin) (Nigeria)

he

Hebrew

he-IL

Hebrew (Israel)

hi

Hindi

hi-IN

Hindi (India)

hr

Croatian

hr-BA

Croatian (Latin) (Bosnia and Herzegovina)

hr-HR

Croatian (Croatia)

hsb-DE\*

Upper Sorbian (Germany)

hu

Hungarian

hu-HU

Hungarian (Hungary)

hy

Armenian

hy-AM

Armenian (Armenia)

id

Indonesian

id-ID

Indonesian (Indonesia)

ig-NG

Igbo (Nigeria)

ii-CN\*

Yi (Peoples Republic of China)

is

Icelandic

is-IS

Icelandic (Iceland)

it

Italian

it-CH

Italian (Switzerland)

it-IT

Italian (Italy)

iu-Cans-CA\*

Inuktitut (Syllabics) (Canada)

iu-Latn-CA\*

Inuktitut (Latin) (Canada)

ja

Japanese

ja-JP

Japanese (Japan)

ka

Georgian

ka-GE

Georgian (Georgia)

kk

Kazakh

kk-KZ

Kazakh (Kazakhstan)

kl-GL\*

Greenlandic (Greenland)

km-KH

Khmer (Cambodia)

kn

Kannada

kn-IN

Kannada (India)

ko

Korean

ko-KR

Korean (Korea)

kok\*

Konkani

kok-IN\*

Konkani (India)

ky

Kyrgyz

ky-KG

Kyrgyz (Kyrgyzstan)

la

Latin

lb-LU

Luxembourgish (Luxembourg)

lo-LA

Lao (Lao P.D.R.)

lt

Lithuanian

lt-LT

Lithuanian (Lithuania)

lv

Latvian

lv-LV

Latvian (Latvia)

mi-NZ

Maori (New Zealand)

mk

Macedonian

mk-MK

Macedonian (Former Yugoslav Republic of Macedonia)

ml-IN

Malayalam (India)

mn

Mongolian

mn-MN

Mongolian (Cyrillic) (Mongolia)

mn-Mong-CN

Mongolian (Traditional Mongolian) (Peoples Republic of China)

moh-CA\*

Mohawk (Canada)

mr

Marathi

mr-IN

Marathi (India)

ms

Malay

ms-BN

Malay (Brunei Darussalam)

ms-MY

Malay (Malaysia)

mt-MT

Maltese (Malta)

nb\*

Norwegian (Bokmål)

nb-NO\*

Norwegian, Bokmål (Norway)

ne-NP

Nepali (Nepal)

nl

Dutch

nl-BE

Dutch (Belgium)

nl-NL

Dutch (Netherlands)

nn-NO\*

Norwegian, Nynorsk (Norway)

no

Norwegian

nso-ZA\*

Sesotho sa Leboa (South Africa)

oc-FR\*

Occitan (France)

or-IN

Oriya (India)

pa

Punjabi

pa-IN

Punjabi (India)

pl

Polish

pl-PL

Polish (Poland)

prs-AF\*

Dari (Afghanistan)

ps-AF

Pashto (Afghanistan)

pt

Portuguese

pt-BR

Portuguese (Brazil)

pt-PT

Portuguese (Portugal)

qut-GT\*

Kiche (Guatemala)

quz-BO\*

Quechua (Bolivia)

quz-EC\*

Quechua (Ecuador)

quz-PE\*

Quechua (Peru)

rm-CH\*

Romansh (Switzerland)

ro

Romanian

ro-RO

Romanian (Romania)

ru

Russian

ru-RU

Russian (Russia)

rw-RW\*

Kinyarwanda (Rwanda)

sa\*

Sanskrit

sa-IN\*

Sanskrit (India)

sah-RU\*

Yakut (Russia)

se\*

Sami (Northern)

se-FI\*

Sami (Northern) (Finland)

se-NO\*

Sami (Northern) (Norway)

se-SE\*

Sami (Northern) (Sweden)

si-LK

Sinhala (Sri Lanka)

sk

Slovak

sk-SK

Slovak (Slovakia)

sl

Slovenian

sl-SI

Slovenian (Slovenia)

sm

Samoan

sma-NO\*

Sami (Southern) (Norway)

sma-SE\*

Sami (Southern) (Sweden)

smj-NO\*

Sami (Lule) (Norway)

smj-SE\*

Sami (Lule) (Sweden)

smn-FI\*

Sami (Inari) (Finland)

sms-FI\*

Sami (Skolt) (Finland)

so

Somali

so-DJ

Somali (Djibouti)

so-ET

Somali (Ethiopia)

so-KE

Somali (Kenya)

so-SO

Somali (Somalia)

sq

Albanian

sq-AL

Albanian (Albania)

sr

Serbian

sr-Cyrl-BA

Serbian (Cyrillic) (Bosnia and Herzegovina)

sr-Cyrl-CS

Serbian (Cyrillic) (Serbia and Montenegro (Former))

sr-Cyrl-ME

Serbian (Cyrillic) (Montenegro)

sr-Cyrl-RS

Serbian (Cyrillic) (Serbia)

sr-Latn-BA

Serbian (Latin) (Bosnia and Herzegovina)

sr-Latn-CS

Serbian (Latin) (Serbia and Montenegro (Former))

sr-Latn-ME

Serbian (Latin) (Montenegro)

sr-Latn-RS

Serbian (Latin) (Serbia)

sv

Swedish

sv-FI

Swedish (Finland)

sv-SE

Swedish (Sweden)

sw

Kiswahili

sw-KE

Kiswahili (Kenya)

syr\*

Syriac

syr-SY\*

Syriac (Syria)

ta

Tamil

ta-IN

Tamil (India)

te

Telugu

te-IN

Telugu (India)

tg-Cyrl-TJ

Tajik (Cyrillic) (Tajikistan)

th

Thai

to\*

Tonga (Tonga Islands)

th-TH

Thai (Thailand)

tk-TM\*

Turkmen (Turkmenistan)

tn-ZA\*

Setswana (South Africa)

tr

Turkish

tr-TR

Turkish (Turkey)

tt\*

Tatar

tt-RU\*

Tatar (Russia)

tzm-Latn-DZ\*

Tamazight (Latin) (Algeria)

ug-CN

Uyghur (Peoples Republic of China)

uk

Ukrainian

uk-UA

Ukrainian (Ukraine)

ur

Urdu

ur-PK

Urdu (Islamic Republic of Pakistan)

uz

Uzbek

uz-Cyrl-UZ

Uzbek (Cyrillic) (Uzbekistan)

uz-Latn-UZ

Uzbek (Latin) (Uzbekistan)

vi

Vietnamese

vi-VN

Vietnamese (Vietnam)

wo-SN\*

Wolof (Senegal)

xh-ZA

isiXhosa (South Africa)

yo-NG

Yoruba (Nigeria)

zh

Chinese

zh-CHS

Chinese (Simplified)

zh-Hans

Chinese (Simplified)

zh-CHT

Chinese (Traditional)

zh-Hant

Chinese (Traditional)

zh-CN

Chinese (Peoples Republic of China)

zh-HK

Chinese (Hong Kong S.A.R.)

zh-MO

Chinese (Macao S.A.R.)

zh-SG

Chinese (Singapore)

zh-TW

Chinese (Taiwan)

zu-ZA

isiZulu (South Africa)