Translate your messages

Updated

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

To localize messages, you’ll follow this process:

  1. Set a language attribute for your workspace 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. 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, 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.

graph LR A[Add language
attribute] --> B[Set up
multi-language message] B --> C[Send
message] C --> D{Does a person's language
attribute match a language variant?} D -->|no| H[Person gets
default message] D -->|yes, lang=es| E[Person gets
Spanish message] D -->|yes, lang=fr| F[Person gets
French message] D -->|yes, lang=de| G[Person gets
German message]

Set up a multi-language message

After you define your language attribute, 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 AI Assistant to translate your content, 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
    Language options where French and auto-translate with AI are checked
  3. Select Auto-translate with AI if you want to use our AI Assistant. Remember to review the results for accuracy. Otherwise, you can learn more about working with translation vendors 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

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
Language options where french and auto-translate with AI are checked

 Not seeing this AI feature?

Make sure “Customer.io AI” is enabled in Privacy, Data, & AI settings. Reach out to an Account Admin if you can’t edit the toggle.

What our AI auto-translates

The Auto-translate tool will translate the following:

It will not auto-translate the following:

  • Images, but it will translate alt text
  • Email layouts in the rich text or code editors
  • Liquid: Static text, attribute values, filter values, etc.
  • Snippets: Rather, you should add liquid conditionals based on people’s language preferences to the snippet file.
  • Text in 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 from its source file.

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 and then re-add the language variants.

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

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
The retry button appears if any translation fails

Languages we don’t auto-translate

This feature can auto-translate most languages we support, but check out the exceptions in our locale list.

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.
The locales uz and tk are checked. A note says auto-translate is not available for tk.

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.

Translating liquid

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:

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:

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

How to work with a translation vendor

Export email to HTML for vendors

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.

flowchart LR A[Create Default
message] -.->F{Test message} D[Export and
send to translator] -->|Get translations
back| E[Add languages] E --> G[Send message] F-.-> |Tests pass|D F-.-> |Tests fail|A

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:
    • 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: Click Actions > Export to HTML.
  • Rich text editor: Click HTML underneath the email header to copy/paste the source code. Then save this to a file to share externally.
  • Code editor: Copy your HTML and save to a separate file.

Add translations 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:
  • If you exported the component syntax (like <x-paragraph>), switch to the code editor, and replace the code with the returned translation.
  • If you exported standard HTML (like <p>), paste in the translated text.
Paste translated text into the blocks of your message.
Click HTML then paste in your translated HTML. You may need to reformat text after pasting.
Paste in the translated HTML.

A/B 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. 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

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
The text direction setting in the advanced options for a paragraph

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.
Welcome to Customer.io! &#x202B;‫مرحبا بك في كستمر.آي.أو‬&#x202C; Let's get started.

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.
There is a red rectangle around the default tab in the top left of a message editor.

Supported languages and locales

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!

Any code with an asterisk (*) is not officially supported by our auto-translate feature. You’ll have to use another service to get an accurate translation.

CodeLanguage/Locale
afAfrikaans
af-ZAAfrikaans (South Africa)
am-ETAmharic (Ethiopia)
arArabic
ar-AEArabic (U.A.E.)
ar-BHArabic (Bahrain)
ar-DZArabic (Algeria)
ar-EGArabic (Egypt)
ar-IQArabic (Iraq)
ar-JOArabic (Jordan)
ar-KWArabic (Kuwait)
ar-LBArabic (Lebanon)
ar-LYArabic (Libya)
ar-MAArabic (Morocco)
ar-OMArabic (Oman)
ar-QAArabic (Qatar)
ar-SAArabic (Saudi Arabia)
ar-SYArabic (Syria)
ar-TNArabic (Tunisia)
ar-YEArabic (Yemen)
arn-CL*Mapudungun (Chile)
as-INAssamese (India)
azAzeri
az-Cyrl-AZAzeri (Cyrillic) (Azerbaijan)
az-Latn-AZAzeri (Latin) (Azerbaijan)
ba-RU*Bashkir (Russia)
beBelarusian
be-BYBelarusian (Belarus)
bgBulgarian
bg-BGBulgarian (Bulgaria)
bn-BDBengali (Bangladesh)
bn-INBengali (India)
bo-CN*Tibetan (Peoples Republic of China)
bi*Bislama
br-FR*Breton (France)
bs-Cyrl-BABosnian (Cyrillic) (Bosnia and Herzegovina)
bs-Latn-BABosnian (Latin) (Bosnia and Herzegovina)
caCatalan
ca-ESCatalan (Catalan)
co-FRCorsican (France)
csCzech
cs-CZCzech (Czech Republic)
cy-GBWelsh (United Kingdom)
daDanish
da-DKDanish (Denmark)
deGerman
de-ATGerman (Austria)
de-CHGerman (Switzerland)
de-DEGerman (Germany)
de-LIGerman (Liechtenstein)
de-LUGerman (Luxembourg)
dsb-DE*Lower Sorbian (Germany)
dvDivehi
dv-MVDivehi (Maldives)
elGreek
el-GRGreek (Greece)
enEnglish
en-029English (Caribbean)
en-ATEnglish (Austria)
en-AUEnglish (Australia)
en-BEEnglish (Belgium)
en-BZEnglish (Belize)
en-CAEnglish (Canada)
en-DEEnglish (Germany)
en-ESEnglish (Spain)
en-FREnglish (France)
en-GBEnglish (United Kingdom)
en-IEEnglish (Ireland)
en-INEnglish (India)
en-JMEnglish (Jamaica)
en-LUEnglish (Luxembourg)
en-MYEnglish (Malaysia)
en-NLEnglish (Netherlands)
en-NZEnglish (New Zealand)
en-PHEnglish (Republic of the Philippines)
en-SGEnglish (Singapore)
en-TTEnglish (Trinidad and Tobago)
en-USEnglish (United States)
en-ZAEnglish (South Africa)
en-ZWEnglish (Zimbabwe)
esSpanish
es-ARSpanish (Argentina)
es-BOSpanish (Bolivia)
es-CLSpanish (Chile)
es-COSpanish (Colombia)
es-CRSpanish (Costa Rica)
es-DOSpanish (Dominican Republic)
es-ECSpanish (Ecuador)
es-ESSpanish (Spain)
es-GTSpanish (Guatemala)
es-HNSpanish (Honduras)
es-LASpanish (Latin America)
es-MXSpanish (Mexico)
es-NISpanish (Nicaragua)
es-PASpanish (Panama)
es-PESpanish (Peru)
es-PRSpanish (Puerto Rico)
es-PYSpanish (Paraguay)
es-SVSpanish (El Salvador)
es-USSpanish (United States)
es-UYSpanish (Uruguay)
es-VESpanish (Venezuela)
etEstonian
et-EEEstonian (Estonia)
euBasque
eu-ESBasque (Basque)
faPersian
fa-IRPersian (Iran)
fiFinnish
fi-FIFinnish (Finland)
fil-PHFilipino (Philippines)
fo*Faroese
fo-FO*Faroese (Faroe Islands)
frFrench
fr-BEFrench (Belgium)
fr-CAFrench (Canada)
fr-CHFrench (Switzerland)
fr-FRFrench (France)
fr-LUFrench (Luxembourg)
fr-MCFrench (Principality of Monaco)
fy-NLFrisian (Netherlands)
ga-IEIrish (Ireland)
gd-GBScottish Gaelic (United Kingdom)
glGalician
gl-ESGalician (Galician)
gsw-FR*Alsatian (France)
guGujarati
gu-INGujarati (India)
ha-Latn-NGHausa (Latin) (Nigeria)
heHebrew
he-ILHebrew (Israel)
hiHindi
hi-INHindi (India)
hrCroatian
hr-BACroatian (Latin) (Bosnia and Herzegovina)
hr-HRCroatian (Croatia)
hsb-DE*Upper Sorbian (Germany)
huHungarian
hu-HUHungarian (Hungary)
hyArmenian
hy-AMArmenian (Armenia)
idIndonesian
id-IDIndonesian (Indonesia)
ig-NGIgbo (Nigeria)
ii-CN*Yi (Peoples Republic of China)
isIcelandic
is-ISIcelandic (Iceland)
itItalian
it-CHItalian (Switzerland)
it-ITItalian (Italy)
iu-Cans-CA*Inuktitut (Syllabics) (Canada)
iu-Latn-CA*Inuktitut (Latin) (Canada)
jaJapanese
ja-JPJapanese (Japan)
kaGeorgian
ka-GEGeorgian (Georgia)
kkKazakh
kk-KZKazakh (Kazakhstan)
kl-GL*Greenlandic (Greenland)
km-KHKhmer (Cambodia)
knKannada
kn-INKannada (India)
koKorean
ko-KRKorean (Korea)
kok*Konkani
kok-IN*Konkani (India)
kyKyrgyz
ky-KGKyrgyz (Kyrgyzstan)
laLatin
lb-LULuxembourgish (Luxembourg)
lo-LALao (Lao P.D.R.)
ltLithuanian
lt-LTLithuanian (Lithuania)
lvLatvian
lv-LVLatvian (Latvia)
mi-NZMaori (New Zealand)
mkMacedonian
mk-MKMacedonian (Former Yugoslav Republic of Macedonia)
ml-INMalayalam (India)
mnMongolian
mn-MNMongolian (Cyrillic) (Mongolia)
mn-Mong-CNMongolian (Traditional Mongolian) (Peoples Republic of China)
moh-CA*Mohawk (Canada)
mrMarathi
mr-INMarathi (India)
msMalay
ms-BNMalay (Brunei Darussalam)
ms-MYMalay (Malaysia)
mt-MTMaltese (Malta)
nb*Norwegian (Bokmål)
nb-NO*Norwegian, Bokmål (Norway)
ne-NPNepali (Nepal)
nlDutch
nl-BEDutch (Belgium)
nl-NLDutch (Netherlands)
nn-NO*Norwegian, Nynorsk (Norway)
noNorwegian
nso-ZA*Sesotho sa Leboa (South Africa)
oc-FR*Occitan (France)
or-INOriya (India)
paPunjabi
pa-INPunjabi (India)
plPolish
pl-PLPolish (Poland)
prs-AF*Dari (Afghanistan)
ps-AFPashto (Afghanistan)
ptPortuguese
pt-BRPortuguese (Brazil)
pt-PTPortuguese (Portugal)
qut-GT*Kiche (Guatemala)
quz-BO*Quechua (Bolivia)
quz-EC*Quechua (Ecuador)
quz-PE*Quechua (Peru)
rm-CH*Romansh (Switzerland)
roRomanian
ro-RORomanian (Romania)
ruRussian
ru-RURussian (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-LKSinhala (Sri Lanka)
skSlovak
sk-SKSlovak (Slovakia)
slSlovenian
sl-SISlovenian (Slovenia)
smSamoan
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)
soSomali
so-DJSomali (Djibouti)
so-ETSomali (Ethiopia)
so-KESomali (Kenya)
so-SOSomali (Somalia)
sqAlbanian
sq-ALAlbanian (Albania)
srSerbian
sr-Cyrl-BASerbian (Cyrillic) (Bosnia and Herzegovina)
sr-Cyrl-CSSerbian (Cyrillic) (Serbia and Montenegro (Former))
sr-Cyrl-MESerbian (Cyrillic) (Montenegro)
sr-Cyrl-RSSerbian (Cyrillic) (Serbia)
sr-Latn-BASerbian (Latin) (Bosnia and Herzegovina)
sr-Latn-CSSerbian (Latin) (Serbia and Montenegro (Former))
sr-Latn-MESerbian (Latin) (Montenegro)
sr-Latn-RSSerbian (Latin) (Serbia)
svSwedish
sv-FISwedish (Finland)
sv-SESwedish (Sweden)
swKiswahili
sw-KEKiswahili (Kenya)
syr*Syriac
syr-SY*Syriac (Syria)
taTamil
ta-INTamil (India)
teTelugu
te-INTelugu (India)
tg-Cyrl-TJTajik (Cyrillic) (Tajikistan)
thThai
to*Tonga (Tonga Islands)
th-THThai (Thailand)
tk-TM*Turkmen (Turkmenistan)
tn-ZA*Setswana (South Africa)
trTurkish
tr-TRTurkish (Turkey)
tt*Tatar
tt-RU*Tatar (Russia)
tzm-Latn-DZ*Tamazight (Latin) (Algeria)
ug-CNUyghur (Peoples Republic of China)
ukUkrainian
uk-UAUkrainian (Ukraine)
urUrdu
ur-PKUrdu (Islamic Republic of Pakistan)
uzUzbek
uz-Cyrl-UZUzbek (Cyrillic) (Uzbekistan)
uz-Latn-UZUzbek (Latin) (Uzbekistan)
viVietnamese
vi-VNVietnamese (Vietnam)
wo-SN*Wolof (Senegal)
xh-ZAisiXhosa (South Africa)
yo-NGYoruba (Nigeria)
zhChinese
zh-CHSChinese (Simplified)
zh-HansChinese (Simplified)
zh-CHTChinese (Traditional)
zh-HantChinese (Traditional)
zh-CNChinese (Peoples Republic of China)
zh-HKChinese (Hong Kong S.A.R.)
zh-MOChinese (Macao S.A.R.)
zh-SGChinese (Singapore)
zh-TWChinese (Taiwan)
zu-ZAisiZulu (South Africa)
Copied to clipboard!
  Contents