Skip to Content
Author's profile photo Mehmet Arziman

UI5ers Buzz #19: Let’s be progressive – Convert an OpenUI5 Application into a Progressive Web App

Progressive Web Apps have opened us a lot of new ways to deliver amazing user experiences on the web. They combine the best of web and the best of apps, regardless of any operating system and browser choice. Once installed they feel and look like native applications without requiring special developing skills. Modern business applications should work on desktop and mobile systems, which is no issue thanks to the responsiveness of PWAs. To top it all: It works completely offline.

SAPUI5 gives us the opportunity to build fast, reliable, and responsive user interfaces for the web. There was already an article about Building a PWA with OpenUI5, but how about converting an existing OpenUI5 Application into a Progressive Web App?

Example: Icon Explorer

The icon explorer is a small tool that allows you to find and preview icons by browsing through categories and tags or just by searching. It loads the SAP icons font, gives an overview of the icons, and shows them in different use cases with UI5 controls. It is a great base for testing the PWA compatibility of UI5.

Live Demo

What do we need?

A default PWA needs:

  • Special meta tags in index.html to tell the browser that this is a web app and to load some icons and to make other modifications.
  • Splash screen and icons to beautify the user interface because Progressive Web Apps need some static content that is shown immediately
  • A Web App Manifest to describe our application. UI5 already requires a manifest, meaning that we can merge them by adding PWA-related terms in the existing manifest.json file
  • A service worker to guarantee offline compatibility

For more details, you can look up the PWA Checklist

After having made all these changes one big problem appears:

We have a lot of synchronous XMLHttpRequests but the service worker is not able to see any of them. To check this just open the Web Application with Chrome, start Developer tools, click on Network to see which files are loaded by the service worker: When you first start the page, the service worker will be registered and installed. When you now reload it, the service worker will start serving the files.

This gives us an overview of all files requested by the icon explorer. You will see that there are already a lot of files loaded by the service worker, but there are still various files not coming from there.

So, what else do we need?

1. Component-Preload

A component preload will combine all needed components in one file. This will help us to get fewer XHRs and to improve the start-up performance for delivering a better user experience. To create a Component-Preload.js file you can either use the SAPUI5 Web IDE or you can do it with Grunt. In this case, we will use Grunt.

We need to create a Gruntfile.js:

module.exports = function(grunt) {
            webapp: 'IconExplorer/src',
            dist: 'dist'

        clean: {
            "preload": ["src/Component-preload.js"],
            "openui5": ['src/openui5']
        "openui5_preload": {
            component: {
                options: {
                    compress: false,
                    resources: {
                        cwd: "src",
                        prefix: "sap/ui/demo/iconexplorer",
                        src: [
                    dest: "src"
                components: "sap/ui/demo/iconexplorer"
    grunt.registerTask('build', ['clean', 'openui5_preload']);
    grunt.registerTask('default', ['build']);

The openui5_preload task will generate our Component-preload.js file which contains our Component.jsmanifest.json and all other .js, .xmland .properties files.

2. Load components asynchronously

We created the Component-preload.js file to reduce the XMLHttpRequests, but the components are still loaded synchronously. Luckily UI5 offers us several opportunities to make things asynchronous.

To fix this, we need to modify the index.html file:

        sap.ui.getCore().attachInit(function () {
            ], function (Shell, ComponentContainer) {
                var oCompContainer = new ComponentContainer({
                    height: "100%"

                // initialize the UI component with async property
                var oComponent = sap.ui.component({
                    async: true,
                    manifestFirst: true,
                    name: "sap.ui.demo.iconexplorer"

                new Shell({
                    app: oCompContainer

3. Load libraries asynchronously

After having all components loaded asynchronously, we also need to do this with the libraries: Just add this to the bootstrapping part of index.html:


This way the libraries are loaded asynchronously, but you have to check, if there are still synchronous requests for libraries. In our case, there are synchronous requests for Avatar.js and library.js file from sap.f-library. This means we must preload the sap.f library.

4. Preload libraries

To preload libraries, we just have to add them to data-sap-ui-libs in bootstrap of index.html:

data-sap-ui-libs="sap.m, sap.ui.layout, sap.ui.core, sap.f"

Now, there are two library requests left: The library-parameters.json files. They are requested, because the browser tries to render the UI before the theme is fully loaded. To solve this, we have to tell the browser in bootstrapping of UI5 in index.html, that it has to wait for the theme:


5. Messagebundles preload

(We do not need this step, when we use the OpenUI5 Nightlies, because after version 1.52 of OpenUI5 the messagebundles are loaded asynchronously. But for older versions we need to preload these files to prevent requests.)

After fixing this, we only have six XHRs. Three of them are asynchronous, so there are just three synchronous requests left:

These three files are the messagebundle files. They are for standard texts in Components, for example the “Search” text of a Search field.

To make them load asynchronously, there is unfortunately no property or tag. We need a workaround:

Firstly, we have to download packaged versions of our libraries with Bower to reach the files, by creating this bower.json file:

    "name": "iconexplorer",
    "dependencies": {
      "openui5-sap.ui.core": "openui5/packaged-sap.ui.core",
      "openui5-sap.m": "openui5/packaged-sap.m",
      "openui5-sap.f": "openui5/packaged-sap.f",
      "openui5-sap.ui.layout": "openui5/packaged-sap.ui.layout"

Secondly, we need to run this command in terminal

$ bower install

Bower will now save our libraries in bower_components directory.

Thirdly, we must must extend our existing Gruntfile.js with one more task called concat:

concat: {
	"sap-ui-messagebundle-preload.js": {
		options: {
			process: function(src, filepath) {
				var moduleName = filepath.substr(filepath.indexOf("resources/") + "resources/".length);
				var preloadName = moduleName.replace(/\//g, ".").replace(/\.js$/, "-preload");
				var preload = {
					"version": "2.0",
					"name": preloadName,
					"modules": {}
				preload.modules[moduleName] = src;
				return "" + JSON.stringify(preload) + ");";
		src: [
		dest: "src/openui5/resources/sap-ui-messagebundle-preload.js"

This task will compress all messagebundle files in one JavaScript file and register each file as preloaded, so it does not need to be requested.

The generated sap-ui-messagebundle-preload.js file by Grunt needs to be called in index.html to be recognized:

<!-- Preload Messagebundle files -->
<script src="openui5/resources/sap-ui-messagebundle-preload.js"></script>

At last, we also have to add this to bootstrapping of UI5 in index.html:


If we do not define a language for our application (e.g with sap-ui-language), UI5 tries to load the messagebundle file according to the browser language. This can lead to requests for very specific language files like de_DE, but UI5 is “only” translated into ~38 languages with one version of German (*de*), causing a language loading fallback. Our preload also contains only these languages, so we have to tell UI5, that it has to load just supported languages. Setting the supported languages to default will avoid any request for languages not existing in UI5.


Finally, our application should now load everything from the service worker. This means that our Progressive Web App is finished and works completely offline. Since Chrome 59, a PWA will also appear in the App Drawer on Android devices, when added to the homescreen, delivering an even more native-like user experience.


This example showed us that Progressive Web Apps are indeed no limitation for OpenUI5. In summary we can say, that it is enough to create a Gruntfile.js, which preloads all components and libraries, to convert our existing OpenUI5 application into a Progressive Web App. But we also have to point out that the icon explorer is a standalone application with no synchronization. For the future we should also consider to examine how OpenUI5 is performing as PWA when it comes to synchronization and data exchange.

Mehmet is a student of Business Information Technology at SAP who is very interested in discovering new technologies and a passionate programmer. Especially mobile and frontend development gives him great pleasure.


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Frank Luzat
      Frank Luzat

      Good one! I'm especially interested in reading "how OpenUI5 is performing as PWA when it comes to synchronization and data exchange."


      I would appreciate a follow up on that topic here!

      Author's profile photo Suriya Pandiyan
      Suriya Pandiyan

      Really good one!

      I am also trying to do this. But I am facing issue with the manifest.json.

      It would be good if you could post your combined manifest.json.


      Author's profile photo Mehmet Arziman
      Mehmet Arziman
      Blog Post Author

      Hi Suriya,

      you can find the hole project and a more detailed description on Github

      best regards.

      Author's profile photo Suriya Pandiyan
      Suriya Pandiyan

      Thanks Mehmet. ?

      I downloaded your project and deployed into SAP system. I am facing this issue.

      I got the same error with my own project too. In GitHub or other servers, it is working fine but in SAP server it doesn't work.


      Could you help me on this?

      Author's profile photo Sergey Chebotarev
      Sergey Chebotarev

      Hello, Mehmet

      Thank  for your post.

      But I have another one problem. In your example has been used JSONMode and it's work OK, but with  ODataModel v2  I have problem.

      After add "sap/ui/model/odata/v2/ODataModel" module as requirement, I have synchronous http request for datajs library. And is problem for Service Worker.

      Please, help me solved this problem.




      Author's profile photo Wolfgang Röckelein
      Wolfgang Röckelein

      Hi Mehmet,

      thanks for the helpful post and git repo!

      Do you know if eg images like the message images from are included in the library preload files you load in the service worker or do have to rely on them being dynamically included in the cache on first use? ie what happens when the first error message that needs to be shown is while being offline?

      IMHO we need a defintive list for each libray what needs to be preloaded, ideally this list should be provided by openui5/sapui5...



      Author's profile photo charanaraj sahus
      charanaraj sahus

      thanks for the helpful post and git repo!,

      i have taken your application from git and tried running in full-stack web IDE, but the below error is coming and not able to achieve PWA for your application and also service worker status is coming as redundant.


      Please, help me solved this problem.



      Author's profile photo Peter Muessig
      Peter Muessig

      Hi Charan,

      the Web IDE seems to generate another index.html file => extended_runnable_file.html which has a complete different bootstrap configuration like the index.html. Either you can find a way to start the real index.html file or use the Node.js environment of the project (unfortunately due to the age of the blog it is still using Grunt and not the UI5 tooling yet).

      To run it with the Node.js environment run:

      npm install

      npm run serve

      Then use your browser to open it and turn it offline to see that it works.

      HTH and BR,


      Author's profile photo Boghyon Hoffmann
      Boghyon Hoffmann

      You can avoid extended_runnable_file.html by disabling the settings mentioned in The issue has been reported last year already but doesn't seem to have high priority.

      Additionally, make sure to enable asynchronous module loading with data-sap-ui-async="true" which replaces preload="async" as of 1.58.2.

      Author's profile photo Andrey Tkachuk
      Andrey Tkachuk

      Hi to All.

      Is there a solution for PWA projects in BTP?
      I have a problem with the manifest file for PWA. It is blocked by the server because it is defined in the manifest tag in the index.html file.

      I tried to run the project from github on BTP cloud and the problem with the manifest file is there.

      Network error: HTTP Status 503 - No application is available to handle this request