Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.


Table of Contents



Although the basics of the i18n mechanism are the same for every part of the ecosystem, the packaging differs if you want to apply this mechanism to the Sonar core platform or to a plugin:

  • Making the Sonar core platform available in a new language requires to develop and publish a new Language Pack plugin. By default Sonar embeds the English Pack. All other Language Pack plugins, like the French Pack plugin, are hosted in the plugins forge (, are maintained by the community and are available through Update Center (category "Localization").
  • This is different for plugins, each plugin is in charge to embed its own translations. Of course supporting i18n mechanism is not mandatory for a plugin but in that case it will only be available in the default implemented language.
titleTo sum up
  • Sonar platform relies on plugins to get translations
  • Sonar plugins embed by themselves all the translations they need

Main principles

The LanguagePack extension point

Sonar I18n mechanism relies on the LanguagePack extension point, implementing this LanguagePack is the first mandatory step.

Here is for instance the EnglishPack class of the Sonar platform:


public class EnglishPack extends LanguagePack {
  public List<Locale> getLocales() {
    return Arrays.asList(Locale.ENGLISH);
  public List<String> getPluginKeys() {
    return Arrays.asList("core", "design", "squidjava");

We can see that:

  • Only one language is available: English
  • Translation is provided for three core plugins : sonar-core-plugin, sonar-design-plugin and sonar-squid-java-plugin. Those plugin keys are mandatories to be able to retrieve translation files.

The translation files


To better understand the following concepts, we're going to use the sonar-i18n-fr-plugin.


Translation bundles

There are 2 types of files for localized messages:

Properties files

  • These are regular properties files with key/value pairs where you will put most I18n translations
  • These files must be stored in the package "org.sonar.l10n" (usually in the directory src/main/resources/org/sonar/i18n" directoryl10n)
  • The name of these files must respect the following convention :
    No Format
    Just for reminder, it is possible to pass arguments to the translated string. Such an entry convention "<plugin key>_<language>.properties", for example ""
  • Messages accept arguments. Such entries would look like:
    No Format
    foo=This is a message with 2 params: the first "
    }" and the second "
  • E.g.: the French translation for the Sonar Squid Java Plugin is "src/main/resources/org/sonar/i18n/"

HTML files

  • In case of They are used for rule descriptions, which might be long and need HTML tags, translations must be put in HTML files
  • These files must be stored in the directory No Format src/main/resources/org/sonar/i18n/{plugin_key}_{language}/ package org.sonar.l10n.<plugin key>_<language>, for example org.sonar.l10n.checkstyle_fr
  • The name of these files must be the key of the rule they translate
  • E.g.: the French translation for description of the Squid Architectural Constraint rule is "src/main/resources/org/sonar/i18n/squidjava_fr/ArchitecturalConstraint.html"
titleFiles must be encoded in UTF-8 encoding

In the Java API, properties files are supposed to be encoded in ISO-8859 charset. Without good tooling, this can be quite annoying to write translation for languages that do not fit in this charset.
This is why we deciced to encode the properties files in UTF-8, and let Maven turn them into ASCII at build time thanks to native2ascii-maven-plugin (check the French plugin POM). This makes the process of writing translations with a standard editor far easier.
HTML files must also be encoded in UTF-8.


Naming conventions for



Here are the conventions you have to know about key namingskeys :

  • For metrics:
    • The key for their name is ""
    • The key for their description is "metric.metric-key.description"
  • For rules:
    • The key for their name is ""
    • The description is in a separate HTML file named "src/main/resources/org/sonar/i18n/plugin-key_locale/rule-key.html"
    • The key for their parameters description is "rule.plugin-key.rule-key.param.parameter-key"
  • For widgets:
    • The key for their title is "widget.widget-key.title"
    • The key for their description is "widget.widget-key.description"
    • Any other key starts with "widget.widget-key."
  • For pages:
    • The key for the name that will be shown on the left menu is ""

For any other key that a Sonar Plugin would define for its own I18n, the key must start with : "plugin-key."






Metric name

metric.ncloc=Lines of code


Metric description

metric.ncloc=Non Commenting Lines of Code


Rule name Instantiation

rule.<repository>.<key>.param.<param key>

Description of rule parameter

rule.pmd.VariableNamingConventions.param.memberSuffix=Suffix for member variables


Widget name



Widget description

widget.alerts.description=Display project alerts


Any other widget message

widget.alerts.tooltip=Threshold is raised

<page key>.page

Page name shown in the left sidebar

<plugin key>.*

Any other keys used by plugin

How to contribute?

You are a plugin developer