Every SAPUI5 app ships to users who read more than one language, sooner or later. Hard-coding German labels because the go-live is in Frankfurt is fine until the same app rolls out to France. The i18n model exists to make that rollout painless.
The i18n Model in 30 Seconds
An i18n model is a ResourceModel that reads key-value pairs from .properties files. You define one file per language — i18n.properties for the default, i18n_de.properties for German, i18n_fr.properties for French. SAPUI5 picks the file matching the user's locale automatically.
Keys live in the manifest, not in the view. Register the bundle once, and every binding expression in the app can reference it.
// manifest.json
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": { "bundleName": "my.app.i18n.i18n" }
}
}
Setting Up Your Properties Files
Keep keys descriptive and hierarchical. title is a trap — six months later nobody knows which screen it belongs to.
# i18n.properties
orderList.title=Sales Orders
orderList.searchPlaceholder=Search by order number…
orderList.noData=No orders found
detail.deliveryDate=Delivery date: {0}
The {0} placeholders get filled at runtime with parameters. They can appear in any position, so translators can reorder the sentence for their language without breaking your code.
Key takeaway: one bundle per language, keyed by locale suffix (
_de,_fr). The default file is the fallback — never leave a key out of it.
Using Texts in XML Views and Controllers
In XML views, the binding expression does all the work. Parameters ride along in the same expression.
<Page title="{i18n>orderList.title}">
<Text text="{
parts: ['i18n>detail.deliveryDate', 'order>DeliveryDate'],
formatter: '.formatter.formatDateText'
}"/>
</Page>
In a controller, grab the bundle from the model and call getText with an array of parameters:
const oBundle = this.getView().getModel("i18n").getResourceBundle();
MessageToast.show(oBundle.getText("orderList.deleted", [sOrderId]));
Language Fallback and Switching
SAPUI5 resolves the locale through a fallback chain: de-AT falls back to de, then to the default file. If a key is missing in the German file but present in the default, the default text renders — no crash, no empty label.
To switch language at runtime, reload the app with the sap-ui-language URL parameter or call Configuration.setLanguage("fr") before the app bootstraps. Changing it after boot requires re-rendering, which is why most apps expose a language picker that simply reloads the page with the new parameter.
Key takeaway: test with the default file empty on purpose once — the gaps show you exactly which keys you forgot to translate.
Common Pitfalls
- Concatenating sentence fragments — "Order" + " " + "deleted" breaks in languages with different word order. Use one key with placeholders.
- Embedding HTML in texts — translators break markup. Keep texts plain and format in the control.
- Ignoring plural forms — English has two forms, Arabic has six. The
getTextplural support ({0, plural, ...}) handles this. - Forgetting the encoding — properties files are ISO-8859-1 by spec; use Unicode escapes for non-Latin characters or save as UTF-8 and declare it.
Say you have a master list and a detail page: wrap every visible string in a key from day one. The cost is a few extra minutes per view, and the payoff is a rollout to a new country that needs zero code changes.
Which i18n mistake bit you hardest — concatenation, plurals, or something worse? Drop it in the comments.