This is a document for developers wanting to provide internationalisation (i18n) support in their plugin's JavaScript code. The guide assumes developers already know how to internationalise your plugin and builds on the techniques described there.
The Web Resource Manager (WRM) provides an internationalisation transformer. When a web-resource is configured with this transformer, specific JavaScript function calls will be found and substituted with a translated value based on the user's or system's configured locale.
If you're creating a new plugin, the easiest way to get started is by using our @atlassian/atlas-fe tool and reading the limitations sub-section below.
For plugins with existing code, there is a manual or automatic way to enable JavaScript internationalisation.
Add the i18n transformer to any web-resource that uses translations:
1 2<web-resource key="my-feature"> <transformation extension="js"> <transformer key="jsI18n"/> </transformation> <dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:i18n</dependency> <resource type="download" name="my-feature.js" location="path/to/my-feature.js"/> </web-resource>
The automatic approach uses the Atlassian Web-Resource Webpack Plugin. Read the webpack plugin's documentation for more information on how to use Webpack with the Atlassian P2 plugin system.
In your JavaScript files, you can use the following function calls:
WRM.I18n.getText('i18n.key.one')
- At runtime, this expression will be replaced with the locale-specific translation
for the key i18n.key.one
.WRM.I18n.getText('i18n.key.with.substitutions', 123, 'foo', ...)
- This variant of the function will replace values
to your translation string at runtime. Specifically, {0}
placeholder in the translation string would be replaced
with the number 123
, {1}
with the string foo
, and so on.To support older platform versions, the AJS.I18n.getText()
function is also replaced, as is any function call that
matches the form <Identifier>.I18n.getText(...)
.
In MyPluginName.properties
:
1 2com.example.plugin.fruit.basket.add.button = Add to basket com.example.plugin.fruit.basket.contains = Fruit basket item count: {0}
Simple message in vanilla JavaScript:
1 2WRM.I18n.getText('com.example.plugin.fruit.basket.add.button')
Formatted message in vanilla JavaScript:
1 2const fruitBasket = ['apple', 'banana', 'apricot']; WRM.I18n.getText('com.example.plugin.fruit.basket.contains', fruitBasket.length);
Tip: You should never write i18n strings that depend on the cardinality of the values passed to it - for instance, "com.example.plugin.fruit.basket.contains.one" or "com.example.plugin.fruit.basket.contains.multiple" - as not all languages have the same pluralisation rules as English. See Pluralising internationalisation strings to find out more on how to write i18n strings that account for plurals.
If you use React and would like to format messages with React elements as parameters,
the @atlassian/wrm-react-i18n
package
will connect your React components with the platform's i18n capabilities. For usage instructions, see the Node package's
readme.
In more recent Server and Data Center product versions, the Web Resource Manager's i18n transform process can accept a pre-compiled list of used i18n keys per JavaScript file. The runtime translation process is significantly faster when the list is provided, which decreases cold cache load times for batch files and other JavaScript resources.
AMPS 8.3 or higher will generate the used i18n keys list when the plugin is compiled.
The Server or Data Center product's platform must include Web Resource Manager version 5.3 or higher.
For every JavaScript file the WRM will serve to the UI, the WRM checks whether the plugin includes an
.i18n.properties
file with the same name. For example, if your atlassian-plugin.xml
defined the following
web-resource:
1 2<web-resource key="my-feature"> <transformation extension="js"> <transformer key="jsI18n"/> </transformation> <dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:i18n</dependency> <resource type="download" name="my-feature.js" location="path/to/my-feature.js"/> </web-resource>
The JavaScript file path/to/my-feature.js
is stored in and retrieved from your plugin JAR. If
a path/to/my-feature.js.i18n.properties
file exists, the WRM will read this file at runtime and opt in to the faster
translation process.
Note that the .i18n.properties
file does not need to be explicitly added to your XML; the WRM will automatically find
it.
The .i18n.properties
file
uses the Java properties file format:
1 2# Any comments will be ignored i18n.key.one=1 i18n.key.two=1 i18n.key.three=2
Each line in the file is a key-value pair separated by an equals sign (=
).
AMPS 8.3 will generate these files by default.
If you use a custom build tool, you can manually generate your own .i18n.properties
files using the format described
above. So long as the files end up in the plugin JAR in the same folder as the .js
file it is for, the WRM will pick
them up at runtime.
The i18n usage file generation can be disabled in AMPS by adding <processI18nUsage>false</processI18nUsage>
to the AMPS <configuration>
block in your project's pom.xml
file.
All limitations stem from getText
not being a real function. Retrieval of message value strings for given keys is done
by the server prior to the JavaScript being served at request-time. This leads to the following limitations:
'
or double quote marks "
as the
delimiters at serve-time..I18n.getText
must not be obfuscated.WRM
or AJS
object identifiers cannot be replaced with an obfuscated name that is
longer than 100 characters.To work around the message key limitations to enable switching messages at runtime, the easiest method is to conditionally use the message value at runtime like so:
Conditionally using message values in JavaScript:
1 2fruitBasket.isFull ? WRM.I18n.getText('com.example.plugin.fruit.basket.delete.button') : WRM.I18n.getText('com.example.plugin.fruit.basket.add.button')
Rate this page: