Skip to Content
Technical Articles

UI5ers Buzz #54: I18n with supportedLocales and fallbackLocale configuration

Internationalization with supportedLocales and fallbackLocale configuration

In this blog post you will learn how to configure the supportedLocales and the fallbackLocale
in your app’s manifest to avoid ‘404 Not Found’ network responses and control the resource bundles.

Note:

Please note that the available properties files for a resource bundle and the specified locales in supportedLocales
need to be in sync. Missing properties files result in 404 responses by the server.
But more severely, a missing entry in supportedLocales leads to a language fallback, even though the texts for the
corresponding language are actually available.

Only use the supportedLocales feature if you are also in control of adding and deleting properties files
for resource bundles. For instance, if you use translation tools which control the lifecycle of properties files
but are not able to update supportedLocales, you cannot make use of the supportedLocales feature yet.

404s, missing translations and other curiosities

When developing apps and working with resource bundles for internationalization (i18n),
you might have run into the following problems:

  • ‘404 Not Found’ responses in the network trace,
    for example for a request to myapp/i18n_de_DE.properties when the client’s locale is "de_DE",
    although there is no translation file for this locale.
  • Resource bundle requests for language “en”,
    such as for e.g. myapp/i18n_en.properties, although the client’s locale is not set to English.

These issues occur more often when a translated text cannot be found in the resource bundle.
The resource bundle then tries to load all potential locale-specific translation files using synchronous requests.
These requests are executed one after the other.
This means that if a particular translation file cannot be found, it causes a delay until the next one is requested.

This not only looks bad when checking the network trace but also comes at a price:
bad performance and unwanted traffic.

But don’t worry! Since UI5 version 1.77 it can be avoided/fixed by
providing the supportedLocales and fallbackLocale configuration in your app’s manifest.

Control over translation or “How to make coffee”

Since UI5 1.77 you can configure the supported locales and the fallback locale for resource bundles.
This enables the client to know in advance which language bundles to request.

You can think of the mechanism for loading a resource bundle and its translation files as a kind of coffee-making process.

Step one: Selection

The bean and the roast

Coffee cherries are picked by hand. The flesh is separated from the bean, and the beans are washed with water.
The defective beans are sorted out, and the high-quality beans are collected.
Afterwards, the beans are roasted and develop their unique flavour.

Fallback Chain

Just like the hand-picking of the cherries is the process for finding locale candidates using a fallback chain.
The fallback chain is a mechanism to determine the locale-specific resource bundle file to load.
A locale can either be a BCP47 language tag or a JDK compatible locale string (e.g. “en-GB”, “en_GB” or “en”).
The fallback chain mechanism is used when loading the resource bundle initially, or when the translation key cannot be found in the already loaded resource bundle.

Part of this fallback chain is the configured fallbackLocale, which defaults to “en”.

The fallback chain produces locale candidates using the following directives:

  1. determine the input language, e.g “de_DE”
  2. remove the region suffix from the locale, e.g. “de_DE” -> “de”
  3. use the fallbackLocale configured, e.g. “en” (defaults to “en”)
  4. use the raw bundle, i.e. “”

Each directive produces a locale candidate, which is then used to create a request.
E.g. “de_DE” is used to create a request for “i18n/i18n_de_DE.properties”.
The directives are executed in order until a resource bundle is loaded (successful request).
The raw bundle “” means that no locale is appended to the requested file. For example, it may be called “i18n/i18n.properties”.

Sample:

input locale: "de_DE"
fallbackLocale: "en"

fallback chain: "de_DE" -> "de" -> "en" -> ""

Step two: Filtering

The brew

The roasted beans are ground before brewing.
There are several ways to brew coffee, but all of them use the same principle:

  1. The ground coffee is mixed with hot water.
  2. The liquid is separated from the used grounds after a specific time.

Supported Locales

Just like the separation of ground and liquid is the filtering of the locale candidates using the supportedLocales.
Only the ones which are in the list of supportedLocales remain.
This way, only resource bundles for configured locales are requested.

input locale: "de_DE"
fallbackLocale: "en"

fallback chain: "de_DE" -> "de" -> "en" -> ""

supportedLocales: ["de", "fr", "en"]

For the given fallback chain only bundle files for "de" and "en" are requested at most, because the list of supportedLocales contains them.
"fr" is not part of the fallback chain so although supported it won't be requested.
Note: If the requested text can be found in "de", "en" will not be requested.

Step three: Result

Fresh coffee

Enjoy your fine cup of coffee!

Clean network trace

The locale for the request is determined, and the translation can be loaded.
The text is presented in the requested locale, and there should be a clean network trace.

BAZINGA!

Sample

File system:

  • i18n/i18n_en.properties English translation
  • i18n/i18n_de.properties German translation

Excerpt from manifest.json

{
	"_version": "1.21.0",
	"sap.app": {
		"id": "sap.ui.demo.todo",
		"type": "application",
        "i18n": {
            "bundleUrl": "i18n/i18n.properties",
            "supportedLocales": ["en", "de"],
            "fallbackLocale": "en"
        },
        "title": "{{appTitle}}"
	},
	"sap.ui5": {
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleUrl": "i18n/i18n.properties",
					"supportedLocales": ["en", "de"],
					"fallbackLocale": "en"
				}
			}
		}
	}
}

Note:

With Manifest version 1.21.0 the sap.app i18n section can hold an object containing bundleUrl, supportedLocales and fallbackLocale.
This is similar to the ResourceModel configuration.

What is loaded with this configuration:

  • de_DE will load i18n_de.properties
  • en_US will load i18n_en.properties
  • fr_FR will load i18n_en.properties

Demo: Before and After

The left-hand side (“Before”) shows the old configuration
without supportedLocales and without fallbackLocale configuration.
The browser’s locale is “en_US”, and no supportedLocales configuration means that all locales are supported.
Therefore, this leads to a request for i18n_en_US.properties, which results in a 404 Not Found response.
The next locale candidate according to the fallback chain is “en”.
The corresponding request for i18n_en.properties succeeds.

The right-hand side (“After”) shows the new configuration
with supportedLocales and with a fallbackLocale configuration.
The browser’s locale is “en_US”, but this locale is not part of the supportedLocales.
The next locale candidate in the fallback chain is “en”.
It is part of the supportedLocales, and the request succeeds.
Bingo!
There is only one request in the network trace, the one for i18n_en.properties.

Moving forward

After using this information and adjusting your manifests, there is no more “back to normal”.
But there is a “back to controlled normal” with new configuration possibilities for your i18n files.
Everything is then under control to provide the best experience and get the most out of your app.

Lessons learned

  • How to configure the app’s manifest regarding i18n
  • How to make coffee

Further Reading

Previous Post: UI5ers Buzz #53: Terminologies in UI5

Author

Profil picture of Tobias SornTobias Sorn is a proud member of the UI5 Core Foundation team. Looks forward to the time after this blog post πŸ™‚
If you liked it, tell your friends about it – if not, tell me πŸ˜‰

7 Comments
You must be Logged on to comment or reply to a post.
  • Great work! Just made the change in my current app, it certainly clears up some of the network errors!

     

    It’s a little weird typing bundleUrl: "i18n/i18n.properties" but that file doesn’t exist – it loads the file i18n/i18n_en.properties. I guess it is no weirder than typing bundleName: "sap.ui.demo.todo.i18n.i18n"!

    • Nevermind – the default I was looking for was

      “bundleUrl”: “i18n/i18n.properties”

      “supportedLocales”: [“”],

      “fallbackLocale”: “”

      So that it loads the default i18n without trying any other locales first. This is useful for developing and removes the 404s πŸ™‚

      • Cool, that it worked out πŸ™‚

         

        The raw locale “” is not explicitly mentioned here to avoid confusion.

        But your solution is perfect:

        The supportedLocales should always match the i18n file suffixes in the filesystem

        E.g.

        • “de” – “i18n/i18n_de.properties”
        • “” – “i18n/i18n.properties”

        would result in supportedLocales: [“”, “de”]

        The fallbackLocale should be explicitly defined and it should be one of the supportedLocales.

  • Sounds like an important feature,

    but I’m a little confused right now:

    I have done a small test (before adding the new supportedLocales, fallbackLocale attributes) of the system behaviour in case of not supported language and I couldn’t reproduce the described scenario:

    I don’t see in the network trace any call to i18n resource with 404 response.

    Moreover, it seems that the contents of the response are returned implicitly according to the described fallback chain (“de_DE” -> “de” -> “en”), while the default language is en.

    i.e. When I enter system language en_GB, I get a response with the contents of the i18n_en file and not a 404 error.

    How exactly does it work?