hilla
hilla copied to clipboard
[i18n] Translation message format
The client-side translate API should support formatting messages in the ICU MessageFormat standard. This enables developers / translators to do basic parameter replacement, number and date formatting, as well as properly handle pluralization and selecting different phrases based on a parameter value. ICU is an industry standard, translators are likely to be familiar with it, and there are a number of implementations in different languages available.
For the implementation, we should choose a Javascript library that implements the ICU MessageFormat standard, and provide its functionality via our own API. Some candidates are listed below. One thing of note is that we want to support ICU on the backend as well later on, for which we'll likely use the ICU4J library. When deciding on a JS library we should do some testing to identify which library closely aligns with ICU4J, so that formatting messages on the backend and frontend ideally works in the same way.
Parameters in messages should be specified using named parameters, as those provide more context to translators than numbered parameters. To support passing named parameters, the translate API should have an optional second parameter that allows passing a Javascript object with key/value pairs.
Examples:
welcome=Welcome {firstName}!
totalcost=Total cost: {price, number, ::.##}€
searchresults=Found {numResults, plural, =0 {no results} one {one result} other {# results}}
formofaddress={gender, select, male {Herr} female {Frau} other {}} {fullName}
translate('welcome', { firstName: 'John' }); // -> Welcome John!
translate('totalcost', { price: 123.456 }); // -> Total cost: 123,45€
translate('searchresults', { numResults: 0 }); // -> Found no results
translate('searchresults', { numResults: 1 }); // -> Found one result
translate('searchresults', { numResults: 3 }); // -> Found 3 results
translate('formofaddress', { gender: 'female', fullName: 'Angela Meier' }); // -> Frau Angela Meier
translate('formofaddress', { gender: 'diverse', fullName: 'Angela Meier' }); // -> Angela Meier
References:
- Formatting Messages | ICU Documentation
- Format Guide - messageformat
- A complete guide to ICU message format & syntax with examples - Lokalise Blog
(Could not find an exact specification, the above are references from individual tools implementing the spec)
Javascript libraries:
I guess we would want to reuse some existing library for this rather than building our own?
Maybe when we have further clarified what the requirements are and if formatting should work the same way it does on the server (using the default I18n provider). At this point the requirements are pretty basic so I'd say a library is not necessary.
I would still encourage using a library from the beginning to avoid causing regressions if we later on switch to using a library that isn't 100% compatible with our own initial implementation.
We had a discussion around this and decided to follow the ICU MessageFormat standard and use a JS library that implements that standard. Will update the issue description accordingly.