Internationalization in Theia

Thu Feb 03 2022 by Mark Sujew

Internationalization (i18n) aims to provide the necessary infrastructure in an application to translate it into different languages/locales. It has been a frequently requested feature for Theia, especially considering that Visual Studio Code which Theia aims to emulate in most aspects has supported i18n since early 2016.

Even though some attempts by contributors have been made in the past, as of mid 2021 Theia still had no support for different locales. Due to increased demand for this feature, we decided to pick it up.

Of course, the main technical inspiration for this feature has been VSCode's i18n implementation. In short: Inside of VSCode, every user-facing string is translated using a localize function call that accepts a key and the English default value. A special build process reads these function calls and extracts every key and default value into a JSON file. These files are then translated and each placed inside of a dedicated VSCode extension, dubbed as a "Language Pack".

Theia after installing the Chinese language pack

How it works

The diagram below shows the basic flow of translation data throughout Theia. After loading VSCode language packs and additional localization contributions into a single localization service at startup, they are requested by the frontend before loading any other code. Having all translation data available at this point allows to use Theia's translation functions even at import time, which is crucial for commands. The localization can be used by every part of the frontend, be it menus, widgets, dialogs, etc.

An overview of the i18n architecture in Theia

Try It!

You can try it out by opening Theia in Gitpod or cloning and compiling it yourself. After installing a language pack of your choice by searching for the language in the extensions tab, run the Configure Display Language command and select your desired language. Theia will automatically reload itself and you'll be presented with a translated user interface.

Using i18n in your own Theia App

Theia's extensibility was kept in mind when designing this feature. Using the nls.localize function imported from the @theia/core package allows for the same behavior as in VSCode. Using the nls-extract command of the @theia/cli tool, you can extract all keys and default values used in the nls.localize calls throughout your codebase.

For example, a call like nls.localize('bye', 'Bye') will get translated into a simple JSON file:

{
    "bye": "Bye"
}

This file can then be translated by hand or by using one of the many online translation services available. A German translation of this file might look like this:

{
    "bye": "Auf Wiedersehen"
}

Compared to VSCode, instead of Language Packs, Theia uses a LocalizationContribution, which is more in line with it's usual dependency injection based approach. In there, you can load your translated JSON files:

// Add this class to your backend code
export class CustomLocalizationContribution implements LocalizationContribution {
    async registerLocalizations(registry: LocalizationRegistry): Promise<void> {
        registry.registerFromRequire('de', require('i18n.de.json'));
    }
}

// ...and add this to your backend dependency injection module
bind(CustomLocalizationContribution).toSelf().inSingletonScope();
bind(LocalizationContribution).toService(CustomLocalizationContribution);

Now, after installing a Language Pack and changing to the de locale, every instance of the nls.localize('bye', ...) call will be translated to it's appropriate German counterpart. Be aware that the option to change to a different language is only available after a corresponding Language Pack has been installed, as the Theia framework depends on them to translate itself.

Conclusion

Internationalization is a very relevant topic for Theia, which is being increasingly adopted throughout the industry. Our contribution ensures that Theia is able to meet the demands of different consumers and users worldwide.

For more information and code examples, you can also take a look at the Theia documentation page.