Skip to content

Localization

Braze automatically collects locale information from user devices after integrating the SDK. The locale contains the language and a region identifier. This information is available in the Braze segmentation tool under Country and Language.

Visit the following iOS and Android/FireOS resources for technical details on how locale is receive based on your platform.

For companies with customers in many countries, handling localization early in your Braze journey can save your companies time and resources. The following article lists the benefits of different orchestration approaches across campaigns and Canvases and also lists different ways users can handle personalization in their messaging.

Orchestration

Campaign

In the “one template for all” approach, localization is applied to a single template in Braze using Liquid. After sending, the dashboard provides aggregated campaign analytics. User-level engagement can be measured using custom segment funnels, for example, by combining Country and Received Campaign filters.

The “one template per country” approach separates templating into different sending locales. After sending, the dashboard reports sending analytics based on each country separately, and any downstream user-level Currents events will also be tied to a specific campaign.

  • Templates benefit from implementing tags for maintenance and tracking purposes.
  • Campaigns can inherit the configurations from the same Braze template and Content Blocks (such as email templates that contain Liquid).
  • Pre-existing campaigns and templates can be duplicated to allow a faster time time-to-value.

Canvas

In the “one journey for all” approach, localization is handled within Canvas Journeys and Liquid to define messaging for each user.

After a Canvas is sent, the dashboard provides aggregated Canvas Analytics, whereas the user level engagement can be measured via custom segment funnels, such as combining Country and Received Canvas Step filters.

In the “one journey per country” approach, the Canvas journey builder provides the flexibility of creating user journeys via multiple Canvas components. These components can be duplicated at the component and overall journey level.

Localization can be achieved through the following methods:

  • Separate Canvases per country, this ensures the complex user journeys are defined at the top of the funnel using audience filters
  • Bespoke user journeys per country, the implementation of Audience Paths to intuitively segment users on a large scale for each journey by creating separate message threads for each country in a single Canvas

Once sent, the dashboard provides dynamic analytics per country and within user-level Currents events based on the customer’s current location.

Personalization

Option 1: Manual entry

Manual entry requires you manually paste your content into the body of your message and use Liquid to conditionally display the correct language to the recipient.

1
2
3
4
5
6
7
8
9
{% if ${language} == 'en' %}
This is a message in English from Braze!
{% elsif ${language} == 'es' %}
Este es un mensaje en español de Braze !
{% elsif ${language} == 'zh' %}
这是一条来自Braze的中文消息。
{% else %}
This is a message from Braze! This will go to anyone who does not match the other specified languages!
{% endif %}

This can be done by using the above format or through the Braze dashboard:

  1. When composing your message, select the Language button to generate Liquid conditional logic for each language you select.
  2. After inserting your templated text into your message, type in different variations for each language. For each field with templating, you should enter the variations after the bracketed segment of templating. The variation should correspond to the language code referenced in the brackets before it.
  3. Test your message before sending it by entering a user’s ID or email to check how a message would appear to an individual depending on their language.

Option 2: Content Blocks

Braze Content Blocks are reusable blocks of content. When a block is changed, all references to that block changes. For example, updates to an email header or footer will be reflected in all emails or to house translations. These blocks can also be created and updated using the REST API, and users can programmatically upload translations.

When building a campaign in the dashboard, Content Blocks can be referenced using tag {{content_blocks.${name_of_content_block}}}. These blocks could contain all translations housed within conditional logic for each language, as shown in option 1, or a separate block for each language can be used.

Content Blocks can also be utilized as a translation management process where content that requires translation is housed within a Content Block, fetched, translated, and then updated:

  1. Manually create a Content Block in the dashboard with the tag “Needs Translation”.
  2. Your service performs a nightly fetch of all Content Blocks using the /content_blocks/list endpoint.
  3. Your service fetches details on each Content Block through the /content_blocks/info endpoint to see which blocks are tagged for translation.
  4. Your translation service translates the body of all “Needs Translation” Content Blocks.
  5. Your service hits the /content_block/update endpoint to update translated content and update the tag to “Translation Complete”.

Option 3: Catalogs

Catalogs allow you to access data from imported JSON objects via API and CSV files to enrich your messages, similar to custom attributes or custom event properties through Liquid. For example:

Create a catalog via the following API call:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
curl --location --request POST 'https://your_api_endpoint/catalogs' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR-REST-API-KEY' \
--data-raw '{
 "catalogs": [
   {
     "name": "translations",
     "description": "My localization samples",
     "fields": [
       {
         "name": "id",
         "type": "string"
       },
       {
         "name": "context",
         "type": "string"
       },
       {
         "name": "language",
         "type": "string"
       },
       {
         "name": "body",
         "type": "string"
       }
     ]
   }
 ]
}'

Add items via the following API call:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
curl --location --request POST 'https://your_api_endpoint/catalogs/translations/items' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR-REST-API-KEY' \
--data-raw '{
 "items": [
   {
     "id": "1",
     "context": "1",
     "language": "en",
     "body": "Hey"
   },
   {
     "id": "2",
     "context": "1",
     "language": "es",
     "body": "Hola"
   },
   {
     "id": "3",
     "context": "1",
     "language": "pt",
     "body": "Oi"
   },
   {
     "id": "4",
     "context": "1",
     "language": "de",
     "body": "Hallo"
   }
 ]
}'

Create a CSV in the following format:

id context language body
1 1 en Hey
2 1 es Hola
3 1 pt Oi
4 1 de Hallo
5 2 en Hey
6 2 es Hola
7 2 pt Oi
8 2 de Hallo
9 3 en Hey
10 3 es Hola
11 3 pt Oi
12 3 de Hallo

These catalog items can them be referenced using personalization, shown below, or selections that allow you to create groups of data.

1
2
3
4
{% catalog_items translations 1 %}
{{items[0].body}} 

//returns “Hey”

Option 4: Add a locale

Add and use locales in your messaging to target users in different languages all within a single email campaign or Canvas.

Option 5: Localization partners

Many Braze partners offer localization solutions, including Transifex and Crowdin. Typically users use the platform alongside an internal team and translation agency. These translations are then uploaded there and are then accessible via REST API. These services also often leverage Connected Content, allowing users to fetch the translations via API.

For example, the following Connected Content calls call Transifex and Crowdin to fetch a translation, leveraging {{${language}}} to identify the correct translation for a given user. This translation is then saved in the JSON block “strings” and referenced.

1
2
{% connected_content https://www.transifex.com/api/2/project/example/resource/example/translation/{{${language}}}/strings :basic_auth semc :save strings %}
{{strings[0].translation}}
1
2
{% connected_content https://api.crowdin.com/api/project/braze-test/export-file?key=you_api_key&language={{${language}}}&file=test.json&export_translated_only=1 :save response %}
{{response.value_1}}

Option 6: Translations in a public Google Sheet

Another translation option includes housing translations in Google Sheets; often, this may be handled in partnership with a translation agency. Translations housed here can be queried using Connected Content. Relevant translation for a user based on their language will then be pulled into the campaign body at the time of sending.

Option 7: Google spreadsheet into a JSON API via SheetDB

This option provides an alternative method of transforming Google Sheets into JSON objects queried via Connected Content. By turning a spreadsheet into a JSON API via SheetDB, you can choose from multiple subscription tiers depending on the cadence of the API calls.

The spreadsheet structure follows the steps in option 4, but SheetDB also provides additional filters to query the objects.

Some users may prefer to implement SheetDB with fewer Liquid and Connected Block dependencies by implementing SheetDB’s search method in GET request calls to filter the JSON objects based on {{${language}}} Liquid tag to automatically return the results for a single language rather than building large conditional blocks.

Step 1: Format the Google sheet

First, build out the Google sheet so that the languages are different objects:

language title1 body1 title2 body2
en Hey 1 Hey2 5
es Hola 2 Hola2 6
pt Oi 3 Oi2 7
de Hallo 4 Hallo2 8

Step 2: Use the language Liquid tag in a Connected Content call

Next, implement the {{${language}}} Liquid tag within a Connected Content call. Note that SheetDB will auto-generate the sheet_id upon creating the spreadsheet.

1
{% connected_content https://sheetdb.io/api/v1/[sheet_id]/search?language={{${language}}} :save result%}

Step 3: Template your messages

Lastly, use Liquid for templating your messages:

1
2
{{result[0].title1}} //returns “Hey”
{{result[0].title2}} //returns “Hey2”
Considerations
  • The {{${language}}} field has to be defined for all users; otherwise, a Liquid conditional block has to be featured as a fallback handler for users without a language.
  • Data modeling within Google Sheets has to follow a different language-driven vertical as opposed to having message objects.
  • SheetDB offers a limited free account and multiple paying options that should be considered based on your campaign strategy.
  • Connected Content calls can be cached. We recommend measuring the projected cadence of the API calls and investigating an alternative approach of calling the main SheetDB endpoint instead of using the search method.
HOW HELPFUL WAS THIS PAGE?
New Stuff!