Skip to content

Module Bundles ​

Every text your module declares lives in its own bundle: an app's i18n/i18n.properties, a library's messagebundle.properties, and the locale files beside them (i18n_de.properties, i18n_en.properties, …). You ship the bundle with the module. Nothing else holds the text: the PHP side declares the thing, the bundle names it.

The keys ​

The SDK fixes the key for every kind of declared text, so it can find the text without being told. The base bundle must carry every required key; a locale file that lacks one shows the English text.

WhatKeyRequiredChecked by
The appappTitle, appDescriptionyes (Core)ui5:sync
Any other artifact whose TITLE or DESCRIPTION is {i18n>key}that keyno; without it the literal staysui5:sync
An Access, Act or Read abilityabilities.<type>.<ability>.title / .descriptionyesui5:sync · Permission Levels
A See abilitythe view's keys—View Visibility
A roleroles.<role>.title / .descriptionyesui5:sync · Permission Levels
A settingsettings.<key>.title / .descriptionyesui5:sync · Reading & Writing
A Customizing rowcustomizing.<catalog>.<code>.<column>yes, for each translatable column that has a literalui5:sync · Customizing
A navigation entryroute.<key>.label (and .title, .description, .icon)the labelui5:nav · Navigation
A Weave doorwayweave.<concept>.labelyesthe registry build · LUX Weave
A messageany key you name in a MessageText—at runtime: an unknown key shows as the key · Actions & Messages
A field in a 422fields.<field>, validation.<field>.<rule>noMutating Actions

The texts sit in the bundle of the module that declares the thing: an ability in the bundle of the app that carries the #[Act], a Weave label in the bundle of the app that declares the #[Weave], not in the hub's.

What stops when a key is missing ​

None of the required keys falls back silently. A missing one stops the step that needs it and names the key and the file it belongs in:

  • ui5:sync stops at the first missing synced text: app titles, abilities, roles, settings, Customizing rows.
  • ui5:nav stops on a missing route.<key>.label and writes no cache.
  • The registry stops on a missing weave.<concept>.label while it is built.

To see every missing synced text at once, before a sync:

bash
php artisan ui5:i18n

It writes nothing, lists each missing key with its file and exits non-zero, so a CI step fails before a deploy would. It runs the same check ui5:sync runs, but collects every missing key instead of stopping at the first.

Which copy of the bundle is read ​

The server reads what the app ships. A packaged app is read from its published resources/ui5/i18n/. An app under a workspace source is read from webapp/ in the browser but from dist/ on the command line, so a key you just typed into webapp/ is invisible to ui5:sync, ui5:nav and ui5:i18n until the app is built. The order is fixed:

bash
# 1. author the keys in webapp/i18n/*.properties
npm run build                        # 2. webapp/ -> dist/
php artisan ui5:app <Name> --refresh # 3. dist/ -> the module's resources/
php artisan ui5:sync                 # 4. the synced texts
php artisan ui5:nav                  # 5. the navigation cache

Translators' files ​

The base bundle is yours and must be complete. The locale files are your translators', and each may be partial: a key it lacks shows in English, and, failing that, from the base bundle. Ship i18n_en.properties even when your base bundle is English, so the English link of the chain exists.

Apostrophes ​

UI5 reads a bundle value as a MessageFormat pattern. A lone ' opens a literal section that swallows every placeholder after it: Can't save {0} shows Cant save {0}. Write '' for an apostrophe in any value that carries a {0}, and prefer ’ (U+2019) in prose, which needs no escaping.