Localize your applications and libraries with property bundles


Enonic XP provides a standard approach to code localizations. This is done by adding so-called resource bundles to your applications, and using the localize() function.

Localize function can be used in both JS controllers and selected views. Detailed documentation for this function is described in the Portal Library docs

To see how this is used in a controller, see lib-i18n in js-libraries.

The labels and texts used in content types, input types and other schemas can also be localized. See how to localize them in localization schemas.

Localization files

The localization files are plain text files, using the properties format (key = value) The files must be placed in a the folder /src/main/resources/i18n/.

Imagine, making an app that should support the following localizations.

The content API, country codes use - as separator rather than _.
  • 'English' (en)

  • 'English US' (en-US)

  • 'New Norwegian' (nn)

  • 'New Norwegian Norway' (nn-NO)

Each locale now needs to have a matching localization file, in the format:

Sample localization bundle
The filenames are case sensitive!


Given the following localization file:

user.greeting = Hello, {0}!
complex_message = Good to see you. How are you doing?
message_url = http://localhost:8080/{0}
message_multi_placeholder = My name is {0} and I live in {1}
message_placeholder = Hello, my name is {0}.
med_\u00e6_\u00f8_\u00e5 = This key contains norwegian characters æ, ø and å

A Javascript controller in the same application may now use the localization as follows:


    var i18n = require('/lib/xp/i18n');
    var complex_message = i18n.localize({
        key: 'complex_message'
    return {
        complex_message: complex_message,

Placeholders are marked with {<number>}. The given number corresponds with the function argument named values and the position of the parameter.

Example of localization with placeholders:


    var i18n = require('/lib/xp/i18n');
    var message_multi_placeholder = i18n.localize({
        key: 'message_multi_placeholder',
        locale: "no",
        values: ["John", "London"]
    return {
        message_multi_placeholder: message_multi_placeholder

The following is considered, in this order:

  • Given as argument to function

  • Language specified on a site (for Site Engine)

  • Language specified in request context

Best match resolving

When localizing, a best match pattern will be applied to select the optimal version. If the locale for a request is resolved to "en-US", XP will look for the localization key in the following order:

  • phrases_en_US.properties

  • phrases_en.properties

  • phrases.properties

If the locale for a request was en, the phrases_en.properties file would be used.

If the locale does not match a any specific file, the default phrases.properties will be used.

If no matching localization key is found in any of the files in a bundle, a default NOT_TRANSLATED will be displayed.

Encoding and special characters

Property keys

Must be in the ISO-8859-1 range, also known as Latin-1 characters. Non-Latin-1 characters use Unicode escape characters, e.g \u00E6 for the Norwegian letter 'æ'.

Property values

Supports any unicode characters

We always recommend storing files with UTF charset.


Specification of the locale format:

A locale is composed of two-letter codes for language, country and variant. Language is required, country and variant are optional.

For the property files, all codes are case sensitive and separated by and underscore (_).

The string-representation of a locale is



  • la= two letter language code as specified by ISO-639

  • CO = optional two letter country code as specified by ISO-3166

  • VA = two letter rarely used variant-code.

A sample locale including vendor specific variant:


Variants are rarely used in XP, and can pretty much be discarded.