Aside the “good path”, where applications appear with the expected theme, there are multiple factors that influence the appearance of the application. This blog post describes
- which technologies perform a theme fallback,
- what their strategies are when performing a theme fallback, and
- how a theme fallback can be detected.
Technologies involved in a theme fallback
First, we’ll focus on theme fallbacks for SAP-provided themes. Here, the application/UI framework performs the theme fallback:
- For SAPUI5 this is handled by sap.ui.core.theming.ThemeHelper, and came only recently (see the commit for openui5) – with 1.114.3 (and newer), 1.108.22, 1.96.25, 1.84.37, and 1.71.60. Enhancing (like Fiori Elements) or embedding (like SAP Fiori launchpad) technologies play a secondary role in deciding on a fallback.
- For Classic UIs this is done in combination of the application framework (SAP GUI for HTML, Web Dynpro ABAP or others) and the underlying UI framework Unified Rendering.
- Other technologies, like applications built with Fundamental Library or UI5 WebComponents, may have their own fallback strategies, but are due to their theming nature (of relying only on the theming parameters of @sap-theming/theming-base-content) less likely to need a theme fallback at all.
An additional layer of theme fallback logic is introduced with Custom themes built with UI theme designer and served with UI theme designers theming service: Here, the theming service is requested with detailed information about the requesting technology (like the library version of an SAPUI5 library); with that it is able to perform a fallback strategy itself – possibly followed by a second fallback initiated by the technology.
Usually, a fallback is initiated when the requested theme (e.g. with the &sap-theme= URL parameter) is not available, has the wrong version, or is rejected by the technology for other reasons.
And here’s the big disclaimer: Every technology has its own theme fallback strategies and they change all the time. So what is written in this blog post will probably age like milk.
Therefore this blog post describes the information available to the technologies. The view might be a bit skewed towards Classic UIs, because I implemented large parts of the theme fallback in Unified Rendering during my time there.
Case: Theme is loaded but rejected
If the theme is loaded at all, then there’s a lot of information at the hands of the technology to decide on a fallback (embedded in the CSS of the theme).
The most significant information is sFallbackThemeId, the technical identifier of another theme – this can even be set in a custom theme and point to a different custom theme:
Technologies should try a fallback to this sFallbackThemeId, if it is available.
If it is not available, the next significant information is the first entry of oExtends, the “extends chain” of a theme. Themes can be built on top of each other: a technologies sap_horizon_dark (Evening Horizon) could extend sap_horizon (Morning Horizon) and only change the “base parameters” (from @sap-theming/theming-base-content) underneath — to not duplicate the technologies CSS. This is the mechanism used for custom themes as well: a custom theme based on sap_fiori_3 (Quartz Light) will have sap_fiori_3 as the first entry of its extends chain – before sap_base_fiori (which is shared by sap_fiori_3 and sap_belize) and baseTheme (the root of all themes).
Therefore, if no sFallbackThemeId is available, technologies should try a fallback to the first entry of the extends chain.
Unless they know better: if the rejected theme is already an SAP-provided theme, it might be appropriate to skip the extends chain and directly fall back to a theme that fits better – e.g. from sap_horizon_hcb (the High-Contrast Black version of Horizon) to sap_fiori_3_hcb (the High-Contrast Black version of Quartz) instead of sap_horizon (Morning Horizon), because the “High-Contrast Black” nature of the theme is more relevant to the user than the right theme family.
That would be realized with a dedicated fallback chain hard-coded in the technologies, which specifies for every SAP-provided theme exactly the SAP-provided theme the fallback should happen to.
And if everything else fails, the technology can still use a fallback strategy for when the theme is not loaded at all.
Case: Theme is not loaded
Here, the technology is left to guess:
- if the theme is an SAP-provided theme, the hard-coded fallback chain described above might be used,
- otherwise the technology can only fall back to a default theme bundled with e.g. the library version.
How to detect a fallback
On the surface level, a fallback is easy to detect: the application does not use the theme you expect.
But beneath the surface, you have to dig deeper and find out what causes the fallback, and where it is performed.
The first question would be: Is the requested theme loaded? If so, you’ll see a 200 Ok response for the themes CSS in the “Network” tab your browsers Developer Tools. If not, this may have various reasons from firewall misconfigurations over missing allowlist entries to servers simply not being available.
If the theme is loaded, you’ll need the versions of
- the technology of your application (e.g. via [CTRL][SHIFT][ALT][P] for SAPUI5 or [CTRL][SHIFT][ALT][V] for Unified Rendering), and
- the theming-content of the technology of your application (via “Help” > “About” in your UI theme designer)
The second question is: How do technology- and theming-content version compare?
In general, the version of the theming-content must be same or higher than the version of the technology. Then it depends on the technology: Unified Rendering promises backwards-compatibility, i.e. newer theming-content versions work with older technology versions; SAPUI5 on the other hand insists on an exact match, i.e. the theming-content version must exactly match the technology version.
To find out if the fallback was initiated by the technology, you’d have to search for the request to the fallback theme in the “Network” tab of your browsers Developer Tools. If there is one, it is likely that the technology initiated the fallback. A fallback initiated by the theming service usually starts with a 302 Found redirect in response to the first theme CSS request.
There are only rare scenarios where a fallback is intended. Most of the time one should try to find out why the fallback happens and solve that problem, instead of making the fallback strategy smarter.
But there’s already a lot going on:
- technology and theming service both have fallback strategies,
- fallback strategies can include the fallback theme id, the extends chain, hard-coded fallback chains, and, as a last resort, a default theme, and
- in case the theme is loaded, most fallbacks happen due to mismatching technology- and theming-content versions.
Let me know in the comments if this blog post helped you understand the situation of fallbacks you’re in with your applications, what your “a-ha moment” was, or how you use the described fallback strategies to implement a scenario that wouldn’t work without.