Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
Showing results for 
Search instead for 
Did you mean: 
Active Contributor


For those who looking for a way to deploy a UI5 app inside a CAP MTA project and make it available from SAP Build Work Zone, I recommend reading my latest blog post. It introduces a streamlined approach leveraging the enhanced tools provided by BAS, allowing you to automatically generate the configurations explained in this blog, eliminating the need for manual configuration settings.


In my previous blog, I wrote about how to create a CAP based Fiori elements app and deploy it to Cloud Foundry. There has been several changes since then:

  • Fiori elements supports OData V4 (List Report and Object Page)

  • Fiori tools has data source option "Local CAP Node.js Project"

  • SAP Cloud Platform Launchpad service (central Launchpad) has been released

In my view, the third one is the most significant change because you no longer need Approuter, Deployer and Launchpad modules in your MTA project.

To know more about the Launchpad service and how to develop applications for central Launchpad, I recommend reading the following blog posts.

In this blog, I'm going to demonstrate how to develop a CAP based Fiori app and deploy it to a central Launchpad.

The source code is available at GitHub.


  • Launchpad service subscription -> tutorial

  • SAP Business Application studio (space type: SAP Cloud Business Application)


  1. Create a CAP project

  2. Add Fiori elements app

  3. Generate mta.yaml

  4. Add XSUAA configuration

  5. Build & Deploy

  6. Configure the Launchpad

1. Create a CAP project

1.1. Generate a new CAP project.
cds init cap-launchpad

1.2. Add sample schema and service by the following command. This generates simple db and service definitions and also mock data. It is enough for demonstration purpose.
cds add samples

1.3. Execute below commands and run the service locally.
npm install
cds watch

1.4. Add UI annotations to srv/cat-service.cds.
annotate CatalogService.Books with @(
UI : {
SelectionFields : [
LineItem : [
{ Value : ID },
{ Value : title },
{ Value : stock }
ID @( title: 'ID' );
title @( title: 'Title' );
stock @( title: 'Stock' );

Fiori preview will look like this.


2. Add Fiori elements app

2.1. Generate Fiori elements app using Fiori tools

2.1.1. Open Yoman UI generator and select "SAP Fiori elements application".

2.1.2. Select "List Report Object Page".

2.1.3. Chose "Use a Local CAP Node.js Project" as Data source and select your CAP project folder and OData service.

2.1.4. Select “Books” as Main Entity.

2.1.5. Type below information.

Module Name fiori
Title Books
Namespace demo
Description Books
Configure advanced options No

Press finish and the Fiori app will be added to app folder.
You might notice that the generated project structure is different from normal UI5 applications, for example, it doesn't have ui5.yaml, package.json, etc. We will add these files in later steps.

Refresh the browser and see that the link to the Fiori app has been added.


2.2. Make adjustments for deploying to Cloud Foundry

Next, let's make some adjustments so that the app can be deployed to Cloud Foundry as a central Launchpad content.

2.2.1. Add fiori/package.json.

*I copied package.json and ui5.yaml files from a project generated by yo fiori-project generator.
"name": "fiori",
"version": "0.0.1",
"devDependencies": {
"@sapui5/ts-types": "1.71.x",
"@ui5/cli": "2.2.6",
"@sap/ui5-builder-webide-extension": "1.0.x",
"bestzip": "2.1.4",
"rimraf": "3.0.2"
"scripts": {
"build": "npm run clean && ui5 build --include-task=generateManifestBundle generateCachebusterInfo && npm run zip",
"zip": "cd dist && npx bestzip ../ *",
"clean": "npx rimraf dist"
"ui5": {
"dependencies": [


2.2.2. Add fiori/ui5.yaml.
specVersion: '1.0'
name: fiori
type: application
propertiesFileSourceEncoding: UTF-8
- "/test/**"
- "/localService/**"
- name: webide-extension-task-updateManifestJson
afterTask: generateVersionInfo
appFolder: webapp
destDir: dist
- name: webide-extension-task-resources
afterTask: webide-extension-task-updateManifestJson
nameSpace: ns
- name: webide-extension-task-copyFile
afterTask: webide-extension-task-resources
srcFile: "/xs-app.json"
destFile: "/xs-app.json"

2.2.3. Add fiori/xs-app.json.

*We will define the destination "cap-launchpad" later.
"welcomeFile": "/index.html",
"authenticationMethod": "route",
"logout": {
"logoutEndpoint": "/do/logout"
"routes": [
"authenticationType": "none",
"csrfProtection": false,
"source": "^/catalog/",
"destination": "cap-launchpad"
"source": "^(.*)$",
"target": "$1",
"service": "html5-apps-repo-rt",
"authenticationType": "xsuaa"

2.2.4. Modify fiori/webapp/manifest.json.

We will make the following changes here.

  • Change the OData path from absolute to relative

        "dataSources": {
"mainService": {
// before "uri": "catalog/",
"uri": "catalog/",

  • Add inbound navigation

    "": {
"crossNavigation": {
"inbounds": {
"fe-inbound": {
"signature": {
"parameters": {},
"additionalParameters": "allowed"
"semanticObject": "Sample",
"action": "display",
"title": "CAP Sample App",
"subTitle": "",
"icon": ""

  • Add configuration

This service name needs to be unique within your account and will appear in the runtime URL of the application. For example, /<>.<>/<pathToFile>
    "": {
"": {
"public": true,
"service": "my_service"


3. Generate mta.yaml

3.1. Generate mta.yaml.

Go back to your project root and execute the following command.
cds add mta

Next, we will add modules and resources to mta.yaml.

3.2. Add destination-content module.

Here you define destinations and service keys for the destinations. After the MTA app has been deployed, you will see two destinations "...html_repo_host" and "..._uaa_fioir" in your subaccount.

Note that the service name "my_service" which we defined in manifest.json appears at section.
- name: fiori-destination-content
- name: uaa_fiori
name: uaa_fiori-key
- name: fiori_html_repo_host
name: fiori_html_repo_host-key
- name: fiori-destination-service
content-target: true
- Name: my_service_fiori_html_repo_host
ServiceInstanceName: fiori-html5-app-host-service
ServiceKeyName: fiori_html_repo_host-key my_service
- Authentication: OAuth2UserTokenExchange
Name: my_service_uaa_fiori
ServiceInstanceName: fiori-xsuaa-service
ServiceKeyName: uaa_fiori-key my_service
existing_destinations_policy: update
no-source: true


3.3. Add ui_deployer.

It uploads zipped web application content into the HTML5 Application Repository.
 - name: fiori_ui_deployer
path: .
- name: fiori_html_repo_host
content-target: true
build-result: resources
- artifacts:
name: fiori
target-path: resources/

Next to it we specify where "fiori" module is located and its build parameters.
 - name: fiori
type: html5
path: app/fiori
builder: custom
- npm run build
supported-platforms: []


3.4. Add resources.

We will add 3 types of services. Destination, html5-apps-repo, and xsuaa.
- name: fiori-destination-service
type: org.cloudfoundry.managed-service
- name: srv-api
service: destination
service-name: fiori-destination-service
service-plan: lite
existing_destinations_policy: update
- Name: cap-launchpad
Description: CAP sample service
Authentication: NoAuthentication
ProxyType: Internet
Type: HTTP
URL: ~{srv-api/srv-url}
HTML5.DynamicDestination: true
HTML5.ForwardAuthToken: true

- name: fiori_html_repo_host
type: org.cloudfoundry.managed-service
service: html5-apps-repo
service-name: fiori-html5-app-host-service
service-plan: app-host
- name: uaa_fiori
type: org.cloudfoundry.managed-service
path: ./xs-security.json
service: xsuaa
service-name: fiori-xsuaa-service
service-plan: application


Along with the destination service, we will create a new destination "cap-launchpad" (this is the destination name we specified in xs-app.json file).

In the old approach (as described in my previous blog), we would directly consume CAP service url in Approuter module with the following way. In the new approach, we don't have Approuter, so direct consumption of the service URL is not possible. That's why we need a destination pointing to the CAP service url.
//old approach
- name: bookshop-app-router
type: approuter.nodejs
path: approuter
- name: bookshop_uaa
- name: bookshop_html5_repo_runtime
- name: bookshop_portal
- name: srv-api
group: destinations
name: srv-api
url: "~{srv-url}"
forwardAuthToken: true

In this document you can find destination configuration in JSON format. I have put the JSON content to mta.yaml file, so that I can consume service url exposed by the CAP service.


4. Add XSUAA configuration

This is the last step before deploy. Add xs-security.json to the project’s root. This file is referenced by the xsuaa service during deployment.
"xsappname": "fiori",
"tenant-mode": "dedicated",
"description": "Security profile of called application",
"scopes": [
"name": "uaa.user",
"description": "UAA"
"role-templates": [
"name": "Token_Exchange",
"description": "UAA",
"scope-references": [


5. Build & Deploy

Finally, run below commands to build and deploy the MTA app to Cloud Foundry.
mbt build
cf deploy mta_archives/cap-launchpad_1.0.0.mtar

Note: Make sure you have installed dependencies for the fiori app before executing build.
cd app/fiori
npm install


After successful deployment, you will see 3 destinations created in your subaccount.


6. Configure the Launchpad

6.1. Go to your Launchpad provider manager and refresh the content.

6.2. Go to content explorer and add the newly created app to content.

6.3. Create a group and assign the app to the group.

6.4. Also, assign the app to Everyone role.

Finally, you can open your Fiori app from the Launchpad.



Compared to my previous blog, fewer objects are required for deploying the app to the Launchpad.

Below objects are no longer required.

  • OData v2 proxy

  • Approuter

  • HTML5 Deployer

  • Launchpad Module

Thanks to this, build and deploy has become much faster.


What's Next?

You can add authentication to CAP service by following the steps in my next blog.

Deploying a CAP based Fiori app to a central Launchpad – Part2: Add Authentication

Labels in this area