Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
last content update was beginning of february 2023.
Please let me know in the comments as soon as something stops working (not expected).


This blogpost intends to show you in a (hopefully) super easy way how to build and deploy proper mta archives in your SAP BTP Cloud Foundry Environment in the context of an SAPUI5 freestyle application. With minor adjustments it will also work fine for any other HTML5 apps as well.

It’ll provide you with a hybrid setup, that allows for 2 different deployment scenarios:

  • Standalone Approuter - maximum flexibility, usage of custom domains etc.

  • Managed Approuter - reduced TCO and resource consumption

Doesn't matter if you would like to build and deploy a new UI5 freestyle app or change the scenario of an existing one (e.g. from managed to standalone approuter) - I will try to provide you with all the info you need to achieve that.

Disclaimer1: I didn't build this combined setup completely from scratch.
For the managed approuter scenario, I have used the corresponding BAS template.
For the standalone scenario, I built upon this github repo from iobert

In both scenarios we will use the HTML5 App Repo service to store our html5 application content conveniently.

Disclaimer2: This blogpost is not a step-by-step developer tutorial for complete beginners but rather a guided template for more experienced developers that know how to work with npm, ui5 and cloud foundry. Please head over to the SAP Dev Tutorials, if you are not yet familiar with UI5 and/or the BTP CF Environment.


  • Access to a SAP BTP subaccount

  • Cloud foundry environment provisioned

  • Launchpad, Workzone or comparable subscription with managed approuter functionality

  • Quota for the HTML5 Application Repository Service

  • Developer-Access to a CF Space

  • SAP Business Application Studio Subscription or comparable local IDE like VSCode

  • CF CLI & Node available locally on your machine or in BAS dev space

TL;DR // Github Source Code Access

If you are in a hurry and would like to browse the final code for "inspirational purposes" :), you can head over to my repo directly: 


Formulating the mta development descriptor(s)

Location of mta.yaml files

The first thing you will probably notice is, that normally the mta.yaml development descriptor is located in the root folder of the project. Of course, we could have just used one mta.yaml file to describe both scenarios, but the aim of this project is to have maximum flexibility.

With 2 separate development descriptors, you can either deploy the built archives side by side in the same space, deploy them in different spaces or even deploy only one of them.

If your project is only going for 1 scenario, 1 mta file in the root folder will be sufficient, though.

In our case the development descriptors are within the folders _build_managed & _build_standalone.
The single dependency to the cloud mta build tool (mbt) is still only within the package.json within the root folder.

Content of the standalone mta.yaml file

Entity Name Description
approuter ui5-standalone-approuter

  • cloudfoundry application which is exposed on a specific route (url)

  • connects to html5 app repo, destination, connectivity and uaa services

html5 deployer html5-deployer

  • uploads the ui5app modules zipped ui5 app to the html5 app repo host

html5 content ui5app

  • references the html5 module folder aka our ui5 application

  • builds and zips it

html5 app repo host ui5-shared-repo-host

  • used for storing and accessing the html5 application content

html5 app repo runtime ui5-standalone-html5repo-runtime

  • used for communication between approuter and html5 app repo host

destination ui5-standalone-destination

  • used for defining destinations to connect to external data services

connectivity ui5-standalone-connectivity

  • used for on-premise type destinations

uaa ui5-standalone-uaa

  • references the xs-security file, which defines the scopes and role templates

Content of the managed mta.yaml file

Entity Name Description
managed approuter config ui5-managed-dest-content

  • defines destination to repo host and uaa instances in destination service, that managed approuter can leverage by using inline-generated service keys

  • values need to match the value in the manifest.json of your html5module

  • destination level per default is set to instance, to use the destination service instance defined under resources, can however be also changed to subaccount.
    This would result in the destinations being created on subaccount level - not recommended because the authorizations may differ for users for subaccount and space level.

html5 deployer ui5-managed-app-content

  • uploads the ui5app modules zipped ui5 app to the html5 app repo host

html5 content ui5app

  • references the html5 module folder aka our ui5 application

  • builds and zips it

html5 app repo host ui5-shared-repo-host

  • used for storing and accessing the html5 application content

destination ui5-managed-dest-srv

  • used for defining destinations to connect to external data services

  • connectivity service is not defined separately, apparently this functionality is part of the managed approuter

uaa ui5-managed-uaa

  • references the xs-security file, which defines the scopes and role templates

Building and Deploying the mta archives

For a condensed version of this section, you can also just read the README of the repo.

Building the mta archives

Run the mbt build command with either of the mta.yaml files either directly or via the npm scripts in the root package.json

  • mbt build -p=cf -s=./_build_standalone -t=../mta_archives

  • mbt build -p=cf -s=./_build_managed -t=../mta_archives

In both cases the build:cf script of the html5module folder will be executed implicitly to generate the ui5 build and zip it under /resources/ and include it as a requirement with the generated mta archives.

more info on the build tool:

Deploying the mta archives

Make sure to first have cf cli with installed multiapps plugin at your hands (either in your local ide terminal or within BAS in your dev space)

  • cf login (in your preferred btp cf space)

  • cf deploy ./mta_archives/ui5-standalone_1.0.0.mtar -f

  • cf deploy ./mta_archives/ui5-managed_1.0.0.mtar -f

in case of undeploy, you can undeploy the mta projects completely using:

  • cf undeploy ui5-standalone --delete-services --delete-service-keys

  • cf undeploy ui5-managed --delete-services --delete-service-keys

These commands are also available as convenient scripts within the root package.json file.


Steps after Deployment

Verify successful deployment

make sure that the terminal finished all deployment tasks successfully, then head over to your cf space in the BTP cockpit and verify, that all service instances and applications have been created and configured correctly.

Also make sure that the html5 module content has been uploaded successfully in the html5 app repo host service instance by using the commands after installing the html5 apps repo cli plugin. (Your correctly configured BAS dev space comes with this installed out of the box)

  • cf html5-list & cf html5-info

more info:
or directly in the readme to find out about additional cli options such as "-u" parameter to display URLs:

Authorize yourself and potential users

While not technically required, I have added scope protection for the paths to access the app content from html5 app repo as well as the used northwind data source via the xs-app files within the html5module folder (managed scenario) and the approuter folder (standalone scenario).

I'd like to raise awareness, that if you aren't doing this, all users that authenticate against your used idp will also be directly able to access your app, if they happen to know the url.

However, when applying the scope checks in the xs-app files, we have to map the scopes to a role template in the xs-security files (located next to the mta dev descriptors).

After successful deployment, the role templates will then be created on your btp subaccount via the xusaa service instances.

Now, you have to create a role collection and add the user role templates in there.

Afterwards you can assign the role collection manually (as a subaccount admin) or via your provisioning tools to you and your other endusers.

Execute the apps

If your user was provisioned with the correct role collection, you can now run the app in the cockpit either via

  • the custom route of the cf application in your space (standalone)

  • the html5 applications tab on the left (managed - requires a a managed approuter e.g. from launchpad service)

In both scenarios the UI5 application content will be retrieved from the shared HTML5 app repo host service instance and the requests to the northwind odata service will be channelled through the respective destination service instance.


Further Read

Configure Fiorilaunchpad/SAP Build Workzone Integration

While it is not really a priority in this blogpost, I understand that many of you also would like to embed the application in a Fiorilaunchpad site of your respective Fiorilaunchpad subscription.

For this, I have added the "crossnavigation" property within the "" of the UI5 app manifest.json.

I won't go into detail, but here are the required steps (assuming you have setup Fiorilaunchpad subscription and roles already):

  • Start the Fiorilaunchpad Site Manager via the provided link within your subaccount subscriptions

  • Make sure to have at least 1 site created

  • Navigate to the Channel Manager on the left and refresh HTML5 Apps Content Channel

  • Navigate to Content Manager > Content Explorer and add the app with id "ui5app"

  • Navigate to Content Manager > My Content and make sure to create at least 1 Role and 1 Group

  • Assign the app to the role and group and make sure the role is including your user

  • Open your site and the app should be visible underneath the corresponding group


Destination service vs Connectivity Service

In the standalone scenario, additionally a connectivity service instance is required if you want to connect against on-premise systems for example via principal propagation. (I suspect this functionality to be included out of the box within the managed approuter)

In this example, we are only connecting against the public non-protected northwind service, meaning it would not be necessary. I however kept it in for the sake of completeness/templating reasons, because if you are not aware of it, weird internal server errors will appear upon connecting against on-premise systems which takes a while to figure out.

More info on this, here:


Shared HTML5 App Repo Host Service Instance

Initially, I also had separate App Repo Host service instances.

However, when you are trying to push HTML5 app content with the same id in 2 different HTML5 App Repo Host service instances within the same space, you'd get the following error during deployment.

[html5-deployer] [ERROR] Upload application content failed { CODE: '1001' } validation error: Application metadata for application ui5app already exists in service instance 26749b39-5a40-4700-8748-af77576b39a2

To support the scenario of deploying both scenarios in the same space, I now refer only to one service instance by using the same id within both mta development descriptors.


Merging other service instances

I could have of course also merged the xsuaa and destination service instances into shared ones across both scenarios.

However, the idea of this whole exercise is not necessarily the side-by-side deployment of both scenarios in the same space, but rather initial templates that you can pick based on your option of choice for your own apps


UI5 Code

This project is not intended to be used as a template for clean ui5 code. Even though I tried to simplify the used ui5 freestyle app as much as possible for educational reasons, there might be many flaws with it.

Usage of v2 OData service, not providing any unit/integration tests and in general outdated code (the app is based on an internal project from 2019) just to name a few.

The main purpose is to demonstrate how the app makes use of the destination service during deployment and the Fiori tools proxy during design time in BAS to connect against external services by mapping the paths respectively in the manifest.json file.

The ui5 app content is almost completely decoupled from the mta development descriptors and other "outside"-content. Only keep in mind to refer to the correct /resources/ filename as the content for the html5 module and the correct id from the UI5 manifest.json within the pathmapping of the xs-app.json of the approuter. This id will also be the id of the app content that is pushed into the html5 app repo host service instance.


Testing against Backends/Services within BAS

It is possible to test your ui5 freestyle app against actual data from backends during design time within your IDE.

For this, navigate to the html5module folder and execute npm run start normally.The ui5.yaml descriptor file is then used to proxy the requests via pathmapping (substitutes the xs-app files)

You can also use the "destination" property of a backend entry to connect live to a global destination of the btp subaccount where your BAS subscription resides in. This way also for example a connection to a backend SAP system via principal propagation authentication and a cloud connector that is connected to your btp subaccount will be possible.

see more info on this here:


Other UI Frameworks

Does the github sample we have composed for you also works for frameworks other than SAPUI5 you might ask. Certainly it does!

The corresponding Cloudfoundry buildpack, the HTML5 Application Repository Service, the MTA build tool and even the Fiorilaunchpad subscription all work fine with non-ui5 HTML5 apps.

Just be sure to configure the manifest.json of the HTML5 module accordingly and adapt the build command that generates the .zip file which is referenced in the mta files.



It’s hopefully not necessary to tell you that a direct deployment set-up via cf cli from your local device or even BAS is more than suboptimal. Please consider creating a build and deployment pipeline to ensure continuous delivery and also to allow for important additional build steps such as codescans and unit test execution.

Potential options are SAPs own CI/CD Service or third party solutions such as „Jenkins as a Service“ or „Github Actions“. I’d personally go for Github Actions, since it integrates the best with your github repository and removes the need to add additional interfaces in the picture.


Kyma Environment

So far this project only comprises deployment to the SAP BTP, Cloud Foundry Environment. I am currently looking into Kyma as well, but for the time being, you might want to have a look at:



Now, you should be able to understand the differences between deploying UI5 freestyle applications with the managed and standalone approuter concepts.

Currently I am not aware of any major problems in this project, which would require a fix, but I haven’t collaborated with anyone else here and 4 or in this case hopefully hundreds of eyes see better than 2, right? 🙂

Therefore, please let me know your feedback, potential improvements and questions in the comments and I'll make sure to follow-up with you on them!

If you enjoyed the content, feel free to leave a like or follow my profile for similar content coming up in the future - Cheers!