Understand Translations
Basic concepts of translating applications in C3 AI suite (i.g., English to French).
As a general rule when approaching application translation, application code should not be hard coding strings for display. It is best if nearly all strings that appear in the application UI are available for translation.
In the C3 AI Suite, application strings are externalized and stored in a Translation Type seed file (for example, en.csv) where each string has a corresponding unique key. The application code then references that key.
For each target language translators receive the en.csv file, translate each string, and create a .csv file for each language (for example, fr.csv) is for French. A single translation key maps to all the different translations for that string. When the application is loaded, the locale, as determined through the browser or user preference, is sent to the server and the string for that locale is returned and rendered.

Provide context for translators

Typically, translators do not translate strings with the context of the entire application. They are solely reliant on the en.csv seed file. This means that the individual strings must provide as much context as possible for the translator to translate the developer externalized strings into equally meaningful strings in the target language(s). This context is crucial for accurate translations as sentence structure and grammar are different across all languages.
For example, given the string “My name is Bobby and I like baseball" where the name and hobby are dynamic:
Incorrect use of translations because the context is too specific:
en.Person.Greeting.name =
"My name is " en.Person.Greeting.hobby =
“ and I like ”
getTranslation('en.Person.Greeting.name') + person.name + getTranslation('en.Person.Greeting.hobby') + person.hobby + ".";


At C3 AI, we follow the ICU Messaging Format for strings externalized to the Translation type seed files. This applies to messages:
  • with arguments
  • with pluralism (1 Object vs 2 Objects)


Arguments are variables and are specified between curly braces ({ }). The argument values are typically data driven and are populated with values at the time of rendering. Translators can then move around the variable element according to the grammar of the target language.
For example, in the string, My name is {name} and I like {hobby} . The name and hobby are variables that are populated at the time of rendering.

Argument format

Some data types (e.g., numbers, date/time, and more) must be formatted according to the UX specifications. There is limited support for formatting being specified and applied through the externalized string.
The argument is in the format of {key, type, format}.


There are languages where the grammar of a sentence change depending on how many objects are referenced in the subject.
The sentence "I found 1 object" changes if the number of objects becomes "0":
  • I found no objects.
  • I found 10 objects.
In such cases, our en.csv file should not contain 2 separate externalized strings. With ICU Message Formatting Standardization, the externalization can be accomplished in one string:
"I found {objCount, plural, =0 {no objects} one {# object} other {# objects}}"
In the above string:
  • objCount is the argument.
  • plural signifies that this argument is a number.
  • =0 signifies to use the subsequent argument if objCount is 0 (the string "no objects").
  • one signifies to use the subsequent argument if objCount is singular (where # represents the objCount number).
  • other signifies use of the subsequent argument if objCount did not satisfy the previous 2 conditions.

Further reads

The formatting of the message can become quite complicated, see the ICU Messaging Format Documentation for further examples. The Technical implementation in Formatting also showcases examples using ICU Message syntax.
The code sandbox provides a hands on experience.