If you have localized your code in certain frameworks you probably came across the term “ICU message” for formatting texts. In this article, we will explain why it exists and how to use it.
Software localization is more than managing plain text translations. Sometimes we need to inject some dynamic values into translations, format the values depending on locale grammar, switch parts of translations depending on the input, etc.
If we don’t have a common, standardized way to do that, we end up with different solutions among libraries. ICU message is a flexible yet powerful syntax to express all nuances of grammar for each language.
These are some popular libraries that support ICU message formatting:
Javascript:
Support for ICU messages differs a bit among libraries, but they have the same foundation.
Note: For exact limitations for each of these libraries it is best to check their official documentation.
Here we will list common usages for ICU message formats. You can use an online ICU editor to explore the options on your own.
Just a plain text.
A text with a placeholder that will be replaced with a variable. Placeholders are wrapped into curly braces.
A text that contains plural content.
In given example count
represents a number variable, but you can name it as you want. Some libraries support #
as an abbreviated placeholder for the count.
Available plural forms are: zero
, one
, two
, many
and other
(required). Not all languages support all plural forms. For instance, English and German support one
and other
only, but Russian supports one
, few
, many
and other
. Check out plural forms per language for more info.
If you want to customize the format for a certain number, you can use additional =<number>
forms. For instance, if you want to print You don't have any photo
instead of You have 0 photos
you would define it with =0
form. Some libraries allow usage of zero
form for all languages for such cases.
Select statements take the form that matches passed variable or defaults to other
form, which is required.
If we pass gender
variable with the value male
to the example, it will print Today is his birthday
.
The base for formatting the numbers is to define them in {variable, number, format}
form, where variable
is the variable we pass, and the format is optional and can have one of a few values. Be aware that not all libraries support all these formats.
which prints The tank is 80% full
.
Numbers are printed in a format for the selected locale. For instance:
The base for formatting the dates and times is to define them in {variable, date|time, format}
form. The variable
is the variable we pass, and the format is optional and can be short
, medium
, long
, full
or some custom format depending on the library used.
which prints Today is: January 10, 2021
.
Any of the elements above can be combined into the same ICU message, and in addition to that plural and select elements can be nested, containing each other.
The structure can get complex and we suggest using ICU message editor that supports syntax highlighting and validation.
We can see that some libraries do not follow all ICU message features, although have the same foundation. But a good thing is that it goes in a good direction to standardize such formats for text localization.
Like this article? Share it!
Aleksa is a Software Engineer at Localizely. Over the past few years, Aleksa has been working in the field of software localization. In his free time, he enjoys playing guitar and writing tech posts.
Subscribe to the Localizely blog newsletter for quality product content in your inbox.
Step into the world of easy localization