I’ve recently started work on a project that will be translated and localized. While translation is rarely prioritized early in the development cycle, leaving translation work until late can cause great sadness if you find you’re weeks away from an intended release date but you’ve built an application with systematic translation flaws.
I’d like to cover five common problems I’ve encountered, so that hopefully you won’t run into them yourself!
1. String Concatenation
In an English-only application, it’s fairly reasonable to concatenate strings. Something like “getString(‘we.found’) + count + getString(‘matching.results’)”. This looks good – the text is externalized, right?
Actually, this turns out to be a huge problem for translation. Many languages require choosing appropriate translations based on gender or other criteria. Translators may also need to re-order sentences to match grammar rules. It’s very important to provide translators with the full context to translate rather than building strings from translated parts. So, always use the equivalent of “getString(‘we.found.n.matching.results’, count)” instead, to allow the translators to see the full string being used and to select the position for the inserted variable.
2. Constrained Layouts
Screen layout is another common problem folks run into. English strings can be much shorter than the equivalent in, say, Polish, or much longer than the equivalent in Japanese. Layouts that seem clean and usable can therefore break terribly when the labels are translated. When text is too long, I’ve seen applications truncate strings, or teams ask for unconventional, abbreviated translations—neither of these should be acceptable outcomes.
In all cases, it’s important to allow full, idiomatic strings that flow smoothly in the layout and don’t require abnormal scrolling or zooming to view content. One tool I highly recommend is pseudolocalization; use it early in the development process to introduce long labels that include non-ascii characters. I’d recommend making the pseudolocalized locale the default locale for your test team.
3. Text in Images
The problem here is fairly straightforward—text used in images will of course not be translated when the user changes languages. These strings are particularly nasty because they elude most tools written to scan for non-externalized strings.
It’s possible to include localized image resources and load an appropriate one for a given language, but this should be used as a last resort. There is great pain in the increased resource size and in the extra effort needed to generate new images when the text inevitably changes.
4. Early Translation
You may have data that is channeled through one path in your application but can be viewed in many places in the UI. It can be tempting to translate at this lower level rather than in each view. Avoid this temptation. The main problem here is that the same text may be translated differently based on context—some languages will have many terms for the same English word, and translators may want to pick the most appropriate word for a given view rather than use the same term for all.
Translating at the view level will also help you avoid bugs where you’re comparing a constant to text that will be translated differently in a different locale. Perhaps the biggest concern, though, is that early translation almost always leads to string concatenation, which we’ve already agreed is a terrible thing.
5. Input Methods
One last tip, be sure to test input methods! Translate a favorite phrase into a variety of languages that use non-ascii characters, and make sure that you can input the text into all user-editable fields and get correct results when that text is stored and then later retrieved and viewed. It’s not uncommon to find that nicely-translated applications fail to correctly accept or render non-ascii user-supplied text. You may also discover input controls that fail to provide input methods for non-ascii characters.
I hope these tips help! And please, please don’t leave translation work to the end of a large project. Reasonable-looking code can hide translation debt and cause great sadness when the team can least afford it. If you spend the time to write some nice tooling for pseudo-translation, importing and exporting strings, and scanning your code for non-externalized strings, you will be richly rewarded for your effort!