Work with Translations
You can use the Properties pane to bind text strings to values that are stored as keys and values in JSON files. You can open and edit the translation JSON files in the code editor, and download and upload the files as application resources.
About Translation Resources
The keys and values for translating your application are stored as JSON files in translation bundles in your application.
The names and locations of your translation bundles are up to you, but you must understand the rules governing the file names and the structure of your bundle to ensure that the bundles are recognized when you run your application.
By default, web and mobile apps will contain a default app-level bundle with the name app
located in the resources/strings
folder of the app. The relative path to the default translations bundle is stored in app-flow.json
. The path identifies the top-level JSON file in the bundle that identifies the translation locales included in the bundle. If you open the application artifact in the code editor you can see the entry for the path to the translation bundle.
"translations": {
"app": {
"path": "./resources/strings/app/nls/app-strings"
}
},
The suggested location for a bundle is resource/strings/<bundle-name>/nls/<bundle-name>-strings.json
, where <bundle-name> is the name for the bundle you create. Bundles can be located where you choose, however the paths to the bundles must be specified in app-flow.json
. For example, if you created a resource folder containing a bundle for the flow MyFlow, the path in app-flow.json
might be similar to ./MyWebApp/flows/MyFlow/resources/strings/MyFlow/nls/MyFlow
. You would use the period ( .
) at the beginning of the path to make it relative to the file.
When using translations in code, you can replace code that produces or uses an untranslated string with code that uses the translations
object to retrieve the translated string from the bundle. For more on the translations
object, see Translations.
Understand the Structure of Translation Bundles
You will want to understand the structure of translation bundles if you want to create additional translation bundles in your application.
The following guidelines describe the structure for the application’s default translation bundle:
-
The bundle contains a root folder named
nls
. -
The
nls
folder should contain a JSON file identifying the translation locales contained in the bundle. -
All bundle files should be JSON files with
–strings.json
appended to the bundle name. (For example, the JSON files for the MyNewPage bundle will be namedMyNewPage-strings.json
.)
The path to the root JSON file in each bundle in your application must be specified in app-flow.json
.

Description of the illustration translations-resources.png
Your bundle contains a JSON file at the root level of the nls
folder that identifies the supported languages, and one or more folders within the nls
folder containing JSON files storing the keys and values of translation strings. By default, the nls
folder contains a folder named root
that contains the root translation file app-strings.json
.
When no additional locales are specified, the root level app-strings.json
file only contains "root": true
. If one additional locale is supported, for example, a French locale and translations, the root level JSON file would contain the following locale identifiers:
{
"root": true,
"fr": true
}
For each locale, the nls
folder should contain a corresponding folder containing a JSON translation file with the translation strings for that locale. The default name for the JSON file in the root
folder is <bundle-name>-strings.json
. If a French locale is added, the nls
folder would also contain a folder named fr
containing a JSON file <bundle-name>-strings.json
. Each translation file contains key/value objects and object metadata. For each object you can include descriptive metadata, including unique id identifiers for the element details and details about the object’s context that can be useful for translators.
Understand Translation Keys for Display Texts
To translate your application into other languages, you need to create translation bundles that store keys and values for the texts in your application’s UI.
When you save a string using the Translatable String popup in the Properties pane, the value for the string is externalized to the translation bundle, and the value of the string is bound to the key in the translation file in that bundle. If you open the page in the Code view you can see the name of the translation bundle and the key bound to the string value. For example, an input label in the Code view code might be similar to <oj-input-text label-hint="Name" id="oj-input-text--452490439-1" value="{{ $page.variables.authors.name }}"></oj-input-text>
.
When you externalize the string, the value of the string is replaced with a string similar to the following that binds it to a key in the translation file:
[[ $application.translations.app.input_text_label_hint_daea ]]
The expression identifies the scope and name of the translation bundle, and the translation key, using the following syntax: <scope>.translations.<bundle-name>.<key>
.
You can also include parameters in the expression by using the syntax <scope>.translations.format('<bundle>', '<key>', {params})
. For example, if you use the expression [[ $application.translations.format('app', 'bind_text_value_372d', { region: $page.variables.Country.region }) ]]
in the UI component, the key-value pair defined in the bundle might be "bind_text_value_372d": "(This country is in {region})"
. In this case, the string “This country is in “ would be translated, and region
would be the value of the page variable.
When you open the translation file in the editor, the file contains a key and value pair similar to the following:
"input_text_label_hint_daea": "Name",
"@input_text_label_hint_daea": {
"description": ""
}
By default, each key-value pair in the translation file contains a description field as part of the metadata for the pair that can be used to provide a description of the value, for example, to provide additional context for the string that can be useful when translating the string. You can modify the file in the editor to add description metadata and other metadata for each key-value pair.
Tip:
You can use the Code view to locate strings in a page that have not been externalized for translation and add the string to the translation bundle. You can use the Audits window to locate all the strings in the application that have not been externalized.
Description of the illustration page-designer-code-translate.png
Generate Translation Keys for Display Texts
For static strings in the UI of your application, you can use the Properties pane to add keys and values for the strings to a bundle for translation.
You can use the Properties pane to generate and add keys for UI components to a translation bundle. When you use the Properties pane to define the translatable string, a key is generated automatically, but you can specify your own key in the dialog box. You can also edit the keys, values and metadata in translation files directly using a text editor.
To generate a key for a string using the Properties pane:
Download Bundles for Translation
You can download translation files to your local system from the Translations tab in the Settings editor when you want to translate the application’s strings with your preferred translation tool or service.
When you download the translation bundles of your visual application, the archive that you download contains the translation files for all of the applications in your visual application. The archive contains a folder for each translation bundle in your application, and each folder contains a file in the .arb
format with the strings to be translated. The file also contains metadata defining the bundle name and path that is used when uploading the file after the strings have been translated. The metadata in the file might be similar to the following:
"@@x-bundleName" : "app",
"@@x-bundlePath" : "webApps/mycontacts/resources/strings/app/nls/app-strings",
When downloading the bundle, you can choose to download an archive containing all strings that are stored in the translation bundle or an archive containing only those strings in the translation bundle that were added or updated since the last time you downloaded the translation bundle. The first time that you download the translation bundle you can only choose to download an archive containing all strings.
To download a translation resource bundle:
Use Translation Strings in JavaScript Files
You can use translation strings in JavaScript files and retrieve the translated text from the bundle when the function is called.
When you use a text string in a JavaScript function, the text string can be externalized to a translation bundle. You can replace the code that produces or uses the untranslated string with code that uses the translations
object to retrieve the translated string from the bundle. When you edit the JavaScript function you will need to either hard code the translation key in the code or pass the key into the function as a parameter. To use the translations
object in the function, you need to pass the object into the function as a function parameter.
For example, you might have a UI component in your page that displays a text string that comes from a JavaScript function that is called by a callModuleFunction action in an action chain. In the action chain, you can pass the translations
object (for example, $application.translations
) to the function and then assign the result to a variable bound to the UI component that displays the string.
To display a translated string used in a JavaScript function:
-
Create a key for the string that you want translated and add the key and string to the translation bundle.
You can use the Make String Translatable button in the Properties pane to create the key in the bundle and generate the expression for the key. Alternatively, you can edit the translation file in the editor to create the key in the bundle and enter the expression for the translation string in the UI component’s Text field in the Properties pane.
-
Copy the expression containing the bundle name and key. The expression is displayed in the Text field of the component after the string is externalized.
The expression might look similar to
[[ $application.translations.app.h1__text_041a ]]
. In this example,app
specifies the bundle name, andh1__text_041a
is the key. The bundle and key are used to evaluate the translated string.$application.translations
specifies that the application-scoped translations object is used. The translations object might also be$flow
or$page
scoped, depending on where the bundle is located. -
Modify the JavaScript function so that the
translations
object$application.translations
can be passed to the function from the action chain.In the following example, the action for calling the function will use
translations
to pass the object to the function.PageModule.prototype.getMessageFromBundle = function(translations) { ... };
-
Edit the function to replace the untranslated text that should be displayed in the component with code that retrieves the translated text using the
translations
object. When the object is available in the function, the bundle name and key are used to retrieve the translated string from the bundle.For example, the function can return a simple translated string:
PageModule.prototype.getMessageFromBundle = function(translations) { ... return translations.app.h1__text_041a; };
You can also include parameters to generate a formatted message:
translations.format('app', 'h1__text_041a', param1, param2)
-
Create an action chain that calls the function (
callModuleFunctionAction
) and assigns the result (assignVariablesAction
) to a variable (in this example,Value
).In this example you can see that the
translations
object is a parameter of the callModuleFunction action that is passed to the function, and that assignVariables assigns the result of callModuleFunction to the page variableValue
."root": "callModuleFunction1", "actions": { "callModuleFunction1": { "module": "vb/action/builtin/callModuleFunctionAction", "parameters": { "module": "{{$page.functions}}", "functionName": "getMessageFromBundle", "params": [ "{{ $application.translations }}" ] }, "outcomes": { "success": "assignVariables1" } }, "assignVariables1": { "module": "vb/action/builtin/assignVariablesAction", "parameters": { "$page.variables.Value": { "source": "{{ $chain.results.callModuleFunction1 }}" } } } }
-
Edit the Text field of the UI component to replace the generated expression with the page variable storing the result of the method. (
Value
).
Description of the illustration page-designer-translations-labelexample.pngTip:
Use the Text field’s Select Variable menu to select the correct page variable
Upload Translated Files
You can upload the resource files containing translated strings in the Translations tab in the Settings editor.
To upload translated file you need to create a ZIP archive containing the ARB files with the translated strings. Before you create the archive, however, you need to modify the file names of the ARB files to append the locale abbreviation to identify the correct locale. For example, to upload an ARB file that contains translations for the French locale, you will modify the file name to <bundle—name>-strings-fr.arb
.
To upload an archive with translation files:
Create Translation Bundles
You can use the Translation tab in the Settings editor to create additional translation bundles for application artifacts, flows and pages.
By default, each web or mobile app contains a translation bundle app
in the app’s top-level resources folder. You can create additional translation bundles for the app in the app artifact’s Settings editor. You can also create bundles for individual flows and pages in the Settings editor for the flow or page when you want the translations to be flow-scoped or page-scoped.
When you create a new bundle in the Translations tab of the Settings editor, the metadata for the new bundle is automatically added to the JSON file of the app, flow or page. For example, if you create a translation bundle for a page in the page’s Settings editor, a resources folder containing the new bundle is created at the page level and the page’s JSON file is updated with the metadata for the bundle.

Description of the illustration translations-bundle-page.png
When you externalize a text for translation, the string and key are added to the nearest available bundle by default. For example, if you create a translation bundle for a page, the strings and keys are added to the page’s bundle when you externalize strings in the page. Strings in other pages are not added to that bundle when they are externalized.
To create a translation bundle:
strings
folder in the resources
folder of the artifact. The strings
and resources
folders are created if they do not exist for the artifact. The path to the new bundle is displayed in the Translations tab. The path is relative to the artifact’s JSON file.