The Localization Blog

In this blog we want to talk about localization in software development. We will explore techniques, tools and best practices in software localization that help you avoid the pitfalls of localization and deliver great products to an international audience.

Angular localization and i18n best practices

May 2019

In this article we will take a closer look on how to efficiently use the built-in Angular internationalization, commonly know as i18n. The basics of internationalization are covered very well on the official Angular website. If you are starting with Angular internationalization read the official documentation first. In this article we will focus on some practical aspects not mentioned in the official documentation but highly important for an efficient and high quality translation workflow.

Place i18n tags always on the innermost HTML element.

This seems rather obvious but Angular let's you place i18n tags at almost every level of your HTML code. The farther away your i18n tag is from the actual translatable text, the more HTML will be inserted into the XLIFF file by the xi18n tool. This will create a huge headache for the translators by making strings much harder to translate. There is also a big risk of translators introducing errors in your HTML resulting in runtime errors of your application.

Let's see some examples:

<div i18n>Title</div> 

will be exported to XLIFF as


If we now decide to wrap "Title" with a span tag we end up with this

<div i18n><span>Title</span></div>

which will be exported to XLIFF as

...<source><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/>Title<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>... 

In practice i18n tags placed on the wrong element happen quite a lot. So watch out for those i18n tags and implement strict and clear guidelines for your team.

Use custom ID's

When you mark a tag with an i18n tag the xi18n tool generates an automatic ID to uniquely identify the string. This ID is nothing more than a hash of the string itself. Naturally if the string is modified, the ID will change. No matter which translation tool you use (Babylon included), it will recognize the new ID as a new string. This forces translators to translate all target languages of the string when in fact maybe only a typo in the invariant string has been corrected. The old (obsolete) string will likely remain in your translation project forever as it has already been translated (this is not the case with Babylon). So make sure you always set a unique custom ID when you use the i18n tag:

<div i18n="@@MainView_PageTitle">Title</div>

We highly recommend using meaningful ID names. Meaningful to translators. It is sometimes very hard for a translator to get any context of the string she is about to translate. Every little bit of context helps and ID's are a very good way of providing it. It's best if you build your ID's using a standardized scheme, e.g. <ViewName>_<ElementName>. This also help avoiding duplicate ID's.

Yes, we know, adding a meaningful ID to every string is tedious and if you did not start this way in a project it will be very time consuming setting all ID's at a later stage. Don't worry, we are currently working to add an auto-ID feature to Babylon. Stay tuned.

Use interpolations

Strings in applications very often contain pieces of information that need to be read from a variable. The text "5 of 10 files have been copied" contains two variables. There are two ways to build this string:

a) Assembly the string by concatenating

files_copied + "of" + total_files + "files have been copied"

b) Use interpolations

"{{files_copied}} of {{total_files}} files have been copied"

Method a makes it very hard for translators. They have no clue the two strings "of" and "files have..." belong together. When using method b on the other hand the xi18n tool writes one string with interpolations to XLIFF. XLIFF editors can interpret interpolations and help translators during translation.

A similar problem arises with plurals like "2 user(s) created" or select expressions like "A red(green) icon indicates...". Both cases can be solved by assembling strings at runtime making it hard for translators. By using plural and select expressions your code will be simpler and life for translators easier.

Coding with localization in mind

Feb. 2017

Localization is usually not as complex as it is sometimes presented. All modern development environments support localization and provide the necessary infrastructure to separate strings to be translated from code.

Localization support is integrated directly into .NET Windows Forms, ASP.NET, WPF and all other .NET target platforms. It can be activated with a few clicks in Visual Studio and usually requires you to insert all your strings into resX files, which are then compiled into satellite assemblies.

Angular offers the i18n attribute to highlight text to be translated, and the xi18n tool to extract these strings to an XLIFF file for translation.

So far so good, but the best platform support is useless if the localization is an afterthought. We've seen many projects over the years that have been developed without localization in mind and then inevitably run into trouble when another language needs to be supported. If all your strings are somewhere in your code, unmarked and not separated, adding a new language becomes a real challenge. Finding all strings and changing or moving them to separate files is almost impossible in a larger project and will almost certainly cause many errors that only your customers will find.

So when it comes to localization a good start is everything. Think about localization before you start coding! And follow these simple rules:

  • Never put any stings into your source code. ALL strings must be placed into separate files (resx files in case of .NET) or marked for localization (i18n in case of Angular). This rule also applies to formatting strings and constants to be displayed as they also need to be translated.
  • Always use the possibility offered by the platforms to name strings with unique ID's.  Come up with a good naming convention for string ID's and stick with it throughout the project. The ID if often a real helpful (sometimes the only) clue for the translator to get some context. It makes a huge difference if a strings is used in a menu, as a label or in a button.
  • Do not use concatenated strings built at run time. Concatenated strings are difficult to localize because they often assume the grammatical order of the invariant language that does not apply to all languages.
  • Avoid using images and icons that contain text or other content that may need to be localized. They are cumbersome and expensive to localize.
  • Allow plenty of room for the length of strings to expand in the user interface. In some languages, phrases can require 50-75 percent more space.
  • Localization is something the client or presentation layer should take care of. It is good practice to keep localization out of the data access and business logic layer and this way avoiding to localize the backend services. This means for example that these layers will only return error codes with error texts in the invariant language. All unhandled exceptions raised in lower layers need therefore be cought by the UI layer to display a localized error message.

Visual Studio and Localization

Nov. 2016

Visual Studio is a very productive development environment but with regards to localization if offers very little. Localizing in Visual Studio is possible by creating resource files (.resX files) for the different target languages and then translating the Windows Forms (C# or VB.NET) or ASP.NET pages (.aspx files). 

Drawbacks when you localize directly in Visual Studio

  • Localizing directly in Visual Studio means generating lots and lots of .resX files that are hard to manage in Visual Studio and often make Visual Studio become slow and instable.
  • No change management for resource strings. In Visual Studio you don't know which string have been changed or added with each new release of your software. To prevent errors all translations have to be verified with each release.
  • No support for a localization process. Software products have a life cycle and with each new release the localization has to be performed again. Without support from a tool this can be a daunting task.
  • Outsourcing translations is cumbersome.

Advantages of using a localization tool

  • Good localization tools support a localization process that becomes part of the general release cycle.
  • The tool keeps track of the translation status of each string. When changing or adding new strings these will be clearly marked as to be reviewed and/or translated.
  • Separation between coding and translating. Developers and translators can work independently from each other.
  • Translations can be outsourced to several external translators in parallel.
  • Support for automatic translations (Google Translator, Azure Translator) and Translation Memory increase the consistency of the translation.
  • Greater productivity when translating due to an environment tailored to translation.