Skip to Content
Technical Articles
Author's profile photo Mio Yasutake

Deploying a CAP based Fiori app to a central Launchpad

*Update*

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.

Introduction

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.

Prerequisites

  • Launchpad service subscription -> tutorial
  • SAP Business Application studio (space type: SAP Cloud Business Application)

Steps

  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

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  : [
            title
        ],
        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 ../fiori-content.zip *",
    "clean": "npx rimraf fiori-content.zip dist"
  },
  "ui5": {
    "dependencies": [
      "@sap/ui5-builder-webide-extension"
    ]
  }
}

 

2.2.2. Add fiori/ui5.yaml.

specVersion: '1.0'
metadata:
  name: fiori
type: application
resources:
  configuration:
    propertiesFileSourceEncoding: UTF-8
builder:
  resources:
    excludes:
      - "/test/**"
      - "/localService/**"
  customTasks:
  - name: webide-extension-task-updateManifestJson
    afterTask: generateVersionInfo
    configuration:
      appFolder: webapp
      destDir: dist
  - name: webide-extension-task-resources
    afterTask: webide-extension-task-updateManifestJson
    configuration:
      nameSpace: ns
  - name: webide-extension-task-copyFile
    afterTask: webide-extension-task-resources
    configuration:
      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
    "sap.app": {
        ...
        "crossNavigation": {
            "inbounds": {
                "fe-inbound": {
                    "signature": {
                        "parameters": {},
                        "additionalParameters": "allowed"
                    },
                    "semanticObject": "Sample",
                    "action": "display",
                    "title": "CAP Sample App",
                    "subTitle": "",
                    "icon": ""
                }
            }   
        }  
    },
  • Add sap.cloud.service configuration

This service name needs to be unique within your account and will appear in the runtime URL of the application. For example, /<sap.cloud.service>.<app.id>/<pathToFile>

    "sap.app": {
        ... 
    },
    "sap.cloud": {
        "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 cap.cloud.service section.

modules:
 - name: fiori-destination-content
   type: com.sap.application.content
   requires:
   - name: uaa_fiori
     parameters:
       service-key:
         name: uaa_fiori-key
   - name: fiori_html_repo_host
     parameters:
       service-key:
         name: fiori_html_repo_host-key
   - name: fiori-destination-service
     parameters:
       content-target: true        
   parameters:
     content:
       subaccount:
         destinations:
         - Name: my_service_fiori_html_repo_host
           ServiceInstanceName: fiori-html5-app-host-service
           ServiceKeyName: fiori_html_repo_host-key
           sap.cloud.service: my_service
         - Authentication: OAuth2UserTokenExchange
           Name: my_service_uaa_fiori
           ServiceInstanceName: fiori-xsuaa-service
           ServiceKeyName: uaa_fiori-key
           sap.cloud.service: my_service
         existing_destinations_policy: update    
   build-parameters:
     no-source: true

 

3.3. Add ui_deployer.

It uploads zipped web application content into the HTML5 Application Repository.

 - name: fiori_ui_deployer
   type: com.sap.application.content
   path: .
   requires:
   - name: fiori_html_repo_host
     parameters:
       content-target: true
   build-parameters:
     build-result: resources
     requires:
     - artifacts:
       - fiori-content.zip
       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
   build-parameters:
     builder: custom
     commands:
     - npm run build
     supported-platforms: []   

 

3.4. Add resources.

We will add 3 types of services. Destination, html5-apps-repo, and xsuaa.

resources:
...
 - name: fiori-destination-service
   type: org.cloudfoundry.managed-service
   requires:
     - name: srv-api
   parameters:
     service: destination
     service-name: fiori-destination-service
     service-plan: lite
     config:
       init_data:
         subaccount:
           existing_destinations_policy: update
           destinations:
             - 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
   parameters:
     service: html5-apps-repo
     service-name: fiori-html5-app-host-service
     service-plan: app-host
 - name: uaa_fiori
   type: org.cloudfoundry.managed-service
   parameters:
     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
   requires:
     - name: bookshop_uaa
     - name: bookshop_html5_repo_runtime
     - name: bookshop_portal
     - name: srv-api
       group: destinations
       properties:
         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": [
        "uaa.user"
      ]
    }
  ]
}

 

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.

 

Conclusion

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

 

Assigned Tags

      74 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo ELI NAIM
      ELI NAIM

      Thanks for the new tutorial,

      But when i'm trying to deploy all i get message:
      "Skipping deletion of services, because the command line option "--delete-services" is not specified."

      so i tried cloning your Github project and deploy it as a sample project, but i get the same error,

      and more then that, on the CF i see only 2 applications, the "srv" & the "db-deployer" app (also in my first deploy).

      Any help?

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi ELI NAIM,

      Regarding the message, that's not an error.

      If you deploy with  "cf deploy <mta_archives> --delete-services", it will first delete all the services associated with your project, and re-create the services. If you don't specivy "--delete-services" option, you will receive this message, but that's fine.

      Second, you don't see HTML5 apps from applications, but you can see them with command "cf html5-list -u -d". (You may need to install CF HTML5 Applications Repository CLI Plugin)

      Can you see your app content from Launchpad as described in Step6?

       

       

       

      Author's profile photo ELI NAIM
      ELI NAIM

      thanks, i'v added “–delete-services”.

      But step 6 is is not clear for me, since i am not a subaccount manager and i dont think i have access for "Launchpad provider manager". Im working on a DEV subaccount (not trail)

      i have exec "cf html5-list -u -d", and i see "demofiori" app, but when i click on it i get 400 error.
      So you have any idea whats next?🙄

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      The url shown in “cf html5-list -u -d” is not executable, the same for me. So I think your project is fine so far.

      To view the app, you need to configure the Launchpad. Have you followed the following steps? You need Launchpad_Admin role to access the Launchpad.

      https://developers.sap.com/tutorials/cp-portal-cloud-foundry-getting-started.html

      Author's profile photo Anubhav Pandey
      Anubhav Pandey

      Dear Mio,

      There is a minor typo in the CDS command line statemet to generate the sample CAP project.

      cds add samles instead of cds add samples

      in case you want to correct it.

       

      Thanks for sharing the content!

       

       

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Anubhav Pandey,

      Thank you for pointing it. I have corrected the command.

      Regards,

      Mio

      Author's profile photo Gregor Wolf
      Gregor Wolf

      Happy New Year!

      Should I see the destination cap-launchpad appear in my subaccount destinations? Unfortunately it doesn't in my deployment. 

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Happy New Year Gregor Wolf!

      Yes, you should see the destination cap-launchpad. It is created from the following configuration in mta.yaml.

      config:
             init_data:
               subaccount:
                 existing_destinations_policy: update
                 destinations:
                   - Name: cap-launchpad
                     Description: CAP sample service
                     Authentication: NoAuthentication
                     ProxyType: Internet
                     Type: HTTP
                     URL: ~{srv-api/srv-url}
                     HTML5.DynamicDestination: true
                     ForwardAuthToken: true
      Author's profile photo Gregor Wolf
      Gregor Wolf

      It didn't create the destination for me. Can you try to proof it? After creating the destination manually all worked fine for me. But of course I want to have also that part automated.

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Please try the following steps.

      1.Clone my git repository.

      //If you deploy to HANA Cloud
      git clone https://github.com/miyasuta/central-launchpad-cap.git
      //If you deploy to HANA Service
      git clone -b hana-service https://github.com/miyasuta/central-launchpad-cap.git

      2. Install dependency

      //Install dependencies for the root project
      npm install
      //Install dependencies for fiori app
      cd app/fiori
      npm install
      

      3. Build & deploy

      mbt build
      cf deploy mta_archives/cap-launchpad_1.0.0.mtar

      For me after completing above steps, the destination was created.

      Author's profile photo Marc Mauri
      Marc Mauri

      Hi Gregor Wolf ,

      The same happens to me after adapting my own project following the instructions. Did you get it in your own project? Did you find what caused it?

      Thanks in advance.

      Best regards,

      Marc

       

      Author's profile photo Gregor Wolf
      Gregor Wolf

      I've followed Mio's instructions but the destination wasn't created. My workaround was to create the destination manually. Haven't investigated further.

      Author's profile photo Marc Mauri
      Marc Mauri

      Hi Gregor and Mio Yasutake, ,

      Solved.

      The fiori-destination-service resource definition is correct in the Github repository, but there is an error in the post text.

      In GitHub:

       - name: fiori-destination-service
         type: org.cloudfoundry.managed-service
         requires:
           - name: srv-api
         parameters:
          service: destination
          service-name: fiori-destination-service
          service-plan: lite
          config:
              init_data:
                  subaccount:

      In the post text, the "config" tag is missing:

       - name: fiori-destination-service
         type: org.cloudfoundry.managed-service
         requires:
           - name: srv-api
         parameters:
           service: destination
           service-name: fiori-destination-service
           service-plan: lite
           init_data:
             subaccount:

      Thanks for your quick answer, Gregor.

      Best regards,

      Marc

       

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Thanks Marc!

      It was my mistake. I have corrected that part.

      Author's profile photo ELI NAIM
      ELI NAIM

      Thanks! Do you know how can i configure live reload to the project?

      like( https://www.npmjs.com/package/ui5-middleware-livereload)

      so each time i'm changing and saving the Fiori app it will reload

      l

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      I have tried below steps to add livereload, but, it's not working.

      1. Add the following script to package.json.

      "start": "ui5 serve --open index.html"

      2. Add the following modules to dev dependency and configure ui5.yaml. (See documentations)

      3. Run the command 'npm start'

      Although the metadata is loaded, when I press 'Go' button, the following error is received in console.

      Uncaught TypeError: Cannot create property '@odata.etag' on string

       

      An alternative is to select "Connect to an OData service" option in step 2.1.3. (instead of "Use a Local CAP Node.js Project”)

      The app generated with this option comes with middleware fiori-tools-appreload with does the same job as ui5-middleware-livereload. If you want to deploy the app generated by this option, you need to adjust build command in package.json (I haven't tried this yet).

      Author's profile photo Anubhav Pandey
      Anubhav Pandey

      Dear Mio,

       

      In Step 5, Build & Deploy, can you add a note to install node dependencies for the Fiori app. Without performing that step, the build will fail.

      Thanks

      Anubhav

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Anubhav,

      Thanks for your suggestion! I have added a note to the Build & Deploy step.

       

      Author's profile photo Marc Mauri
      Marc Mauri

      Hi Mio,

      thank you very much for sharing your knowledge. With your previous blog, I learned how to add a launchpad module to my CAP app and I am now learning how to integrate the new launchpad service. Amazing blogs!

      Just a question about the Approuter module. You mentioned that Approuter is no longer needed (in this scenario), but is needed, for example, in multitenant applications, being required for onboarding consumer tenants.

      My question is, given that my multitenant CAP application already needs an Approuter module, I would like to use it instead of creating a new destination (cap-launchpad in your example). Is there any reason to avoid this approach?

      Thanks in advance.

      Best regards,

      Marc

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Marc,

      Thanks for your positive comment.

      I haven't created multitenant app myself, so I'm not confident to answer your question, but in Marius's blog comment he says that there can be many good reasons to continue using an approuter. Depending your use cases, you may find it more appropriate to use Approuter.

      Regards,

      Mio

      Author's profile photo Denis Galand
      Denis Galand

      Hello,

      This blog looks amazing, I'm trying to follow the steps but I'm lost at

      step 3.2

      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.

      Is there a command missing in the guide? So far I only see that we change the source code to deploy afterwards, or did I miss something?

      Author's profile photo Gregor Wolf
      Gregor Wolf

      Have you tried the Git repository and the steps that Mio described in the comment https://blogs.sap.com/2020/12/15/deploying-a-cap-based-fiori-app-to-a-central-launchpad/comment-page-1/#comment-546604

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Dennis,

      Thanks for your comment.

      There's no hidden steps. All you need is mta.yaml configuration and it will automatically create destinations during deployment.

      Author's profile photo Denis Galand
      Denis Galand

      No, I tried to follow the guide on the blog, but I will have a look at it.

      I think I got confused that we are talking of the deploy from step 5 in the step 3.2, thanks 🙂

      Author's profile photo Max Schnürle
      Max Schnürle

      Hi everyone,

       

      thank you for that very helpful post.

      during the build command I am receiving the error :

      Error Message:
      [npm translator] Could not locate module @sap/ui5-builder-webide-extension via resolve logic (error: Cannot find module ‘@sap/ui5-builder-webide-extension/package.json’ from ‘/home/user/projects/cap-launchpad/app/fiori’) or in a collection

      I can not find any hint in the web what this is caused by. package.json file is maintained correctly. Do you have any idea?

      Best Regards

      Max

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Max,

      Thanks for your comment.

      Regarding the error, have you installed dependencies for fiori app?

      If not, please try the following commands.

      cd app/fiori
      npm install

      Best regards,

      Mio

      Author's profile photo pieter teirlynck
      pieter teirlynck

      'npm clear cache --force' and then 'npm i' worked for me.

      Author's profile photo Max Schnürle
      Max Schnürle

      cool thanks. that solved it:)

      one further question: as soon as I deploy 2 html5 apps within the MTA project Im only able to view and access one app via the launchpad service. does that mean app router is still required as soon as you have multiple html5 apps?

      BR
      Max

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      When you have multiple html5 apps, I guess you only need multiple destinations pointing to each app. You need Approuter if your deployment target is not the launchpad.

       

      Author's profile photo Aaron Schwarz
      Aaron Schwarz

      Hi Mio,

      when trying to deploy the application I get the following error:

      Binding service instance “ivc-em” to application “ivc-srv”...
      Uploading content module “ivc-ui-deployer” in target service “ivc-html5-repo-host”...
      Error uploading content module “ivc-ui-deployer” in service “ivc-html5-repo-host”: org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException: com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation ‘Upload File’: Upload application content failed { CODE: ‘1001’ } validation error: Could not find applications in the request.

      Any idea why this might occur? Maybe I got a wrong config for my UI-deployer?

      ############## UI DEPLOYER #########################
      - name: ivc-ui-deployer
      type: com.sap.application.content
      path: .
      requires:
      - name: ivc-html5-repo-host
      parameters:
      content-target: true
      build-parameters:
      build-result: resources
      requires:
      - artifacts:
      - fiori-content.zip
      name: fiori
      target-path: resources/
      - artifacts:
      - IVC-content.zip
      name: ui-IVC
      target-path: resources/
      - artifacts:
      - MMM-content.zip
      name: ui-MMM
      target-path: resources/
      - artifacts:
      - Posting-content.zip
      name: ui-posting
      target-path: resources/
      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Aaron,

      First, ui deployer needs corresponding html5 module. Please check if you have specified all 4 html5 modules required for the ui deployer.

       - name: fiori_ui_deployer
         ...
         build-parameters:
           build-result: resources
           requires:
           - artifacts:
             - fiori-content.zip
             name: fiori //this
             target-path: resources/
       - name: fiori
         type: html5
         path: app/fiori
         build-parameters:
           builder: custom
           commands:
           - npm run build
           supported-platforms: []   

      Second, artifacts name "xxx-content.zip" comes from scripts in package.json of each app.

      Make sure the names match with the ones in mta.yaml.

        "scripts": {
          "build": "npm run clean && ui5 build --include-task=generateManifestBundle generateCachebusterInfo && npm run zip",
          "zip": "cd dist && npx bestzip ../fiori-content.zip *",
          "clean": "npx rimraf fiori-content.zip dist"
        },

       

      Author's profile photo Aaron Schwarz
      Aaron Schwarz

      My html5 modules are looking like this:

        ##############    UI - IVC   #########################
        - name: ui-IVC
          type: html5
          path: app/ui-IVC
          build-parameters:
           builder: custom
           build-result: dist
           commands:
           - npm run build
           supported-platforms: []
          requires:
            - name: srv_api
              group: destinations
              properties:
                forwardAuthToken: true
                name: srv_api
                url: ~{srv-url}

       

       

      My package.json script looks like this:

      "scripts": {
      "build": "npm run clean && ui5 build --include-task=generateManifestBundle generateCachebusterInfo && npm run zip",
      "zip": "cd dist && npx bestzip ../IVC-content.zip *",
      "clean": "npx rimraf IVC-content.zip dist"
      }

      My folder structure looks like this:

      Do you see any error?

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Aaron,

      I don't see any error in your project.

      After executing build, do you see zip content under your app and resources folders?

      Author's profile photo Aaron Schwarz
      Aaron Schwarz

      There are ZIP-files in the App folder, but my resources folder is empty. Any idea why?

      Author's profile photo Aaron Schwarz
      Aaron Schwarz

      Mio Yasutake I got it resolved now by changing the build-result path of my UI-module:

       ##############    UI - IVC   #########################
        - name: ui-IVC
          type: html5
          path: app/ui-IVC
          build-parameters:
           builder: custom
           build-result: .
           commands:
           - npm run build
           supported-platforms: []
      

       

      Now the build is successful, however when deploying I get this error:

      ivc-ui-deployer] [ERROR] Upload application content failed { CODE: ‘1001’ } validation error: manifest.json not found.

       

       

       

      Author's profile photo Holger Schäfer
      Holger Schäfer

      Hi Miro,
      great Blog!

      I also ran into an issue last week, since SAP changed it a little bit and i always had to refresh apps inside launchpad.

      BTW: The current BAS Template generates instance: and it took my a lot of time to figure out, that is will only work with subaccount: for whatever reason.

      If you want to see your service in HTML5 Applications view, you can add before init_data in ressources

            HTML5Runtime_enabled: true
            version: 1.0.0
            init_data:
      

      Best Regards
      Holger

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Holger,

      Thanks for the information.

      I have added the parameters as you suggested, and now I can see html5 app url when I execute cf html5-list -u -d command as below.

      However, when I click on the url, I receive authorization error.

      Can you open the html5 from the url without issue?

       

      Author's profile photo Holger Schäfer
      Holger Schäfer

      Hi Miro,

      my output looks totally different with no valid uri

      - - - stzh.rfcm stzh_rfcm_stzh_rfcm_html_repo_host - https://sap.com/DUMMY_URL
      - - - stzh.rfcm stzh_rfcm_uaa_stzh_rfcm - https://api.authentication.eu10.hana.ondemand.com

      But i can open the url directly from cockpit HTML5 Applications view.

      https://xxxx.launchpad.cfapps.eu10.hana.ondemand.com/stzhrfcm.stzhrfcmmanage-1.0.0/Component.js

      By default it will use index.html (nor part of my project) but using Component.js will show the page.

       

      Best Regards
      Holger

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Holger,

      Thanks for your quick reply.

      I'm using a trial account so HTML5 Applications menu is not available.

      I tried to put the url + /Component.js to the browser, but the authorization issue persists.

      Best regards,

      Mio

       

      Author's profile photo Aracely Chavez
      Aracely Chavez

      Hi, maybe you already found out, but sounds like you need to replace "cpp" with "launchpad".

      https://developers.sap.com/tutorials/appstudio-fioriapps-mta-build-deploy.html  (Step 4.4)

      It worked for me, thanks for your post!

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Thanks for the info, Aracely!

      I'm able to directly open the app from the browser.

      Author's profile photo Heise Brian Nicholas
      Heise Brian Nicholas

      Hi Mio! Thanks for the amazing content. I have a question, though. You're current project explains how to add a Fiori UI to a node.js project. Do you happen to know or have any resources for doing the same thing with a CAP Java project? Thanks!

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Heise,

      Thanks for your comment.

      I haven't tried CAP Java project, but here's a sample repo of CAP on Java with Fiori front end.

      https://github.com/SAP-samples/cloud-cap-samples-java

      Regards,

      Mio

      Author's profile photo Heise Brian Nicholas
      Heise Brian Nicholas

      Thanks for letting me know! Keep up the good work. ^_^

      Author's profile photo Virender Singh Rana
      Virender Singh Rana

      Hi Aaron/Miro,

      I also ran into same issue as below:

      Error uploading content module "testapp_ui_deployer" in service "testapp_html_repo_host": org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException:
      com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation 'Upload File':
      Upload application content failed { CODE: '1001' } validation error: Error while parsing request; Error: Unknown system error -122:
      Unknown system error -122, open 'tempFolder/wrGW-m-GfTiKKW0UKW7KWJ2-.zip'

       

      What was the solution for it ? Can you please share. Thanks in advance.

      Regards,

      Virender.

       

      Author's profile photo Virender Singh Rana
      Virender Singh Rana

      Complete error message:

      Executing action 'abort' on operation d1c5c9e5-88e9-11eb-bb39-eeee0a9e29bb...
      OK
      Uploading 1 files...
      /home/user/projects/testapp/mta_archives/testapp_0.0.1.mtar
      OK
      Operation ID: a76bfcd3-88f1-11eb-b412-eeee0a8a83df
      Deploying in org "mck-coupa-cf" and space "mck-coupa-space"
      Detected MTA schema version: "3"
      Detected deployed MTA with namespace "null", ID "testapp" and version "0.0.1"
      Detected new MTA version: "0.0.1"
      Deployed MTA version: "0.0.1"
      Processing service "testapp_html_repo_runtime"...
      Processing service "testapp_html_repo_host"...
      Updating application "testapp-approuter"...
      Application "testapp-approuter" attributes are not modified and will not be updated
      Unbinding service instance "testapp_html_repo_runtime" from application "testapp-approuter"...
      Binding service instance "testapp_html_repo_runtime" to application "testapp-approuter"...
      Uploading application "testapp-approuter"...
      Started async upload of application "testapp-approuter"
      Stopping application "testapp-approuter"...
      Staging application "testapp-approuter"...
      Application "testapp-approuter" staged
      Starting application "testapp-approuter"...
      Application "testapp-approuter" started and available at "mck-coupa-cf-mck-coupa-space-testapp-approuter.cfapps.eu10.hana.ondemand.com"
      Service key "testapp_ui_deployer-testapp_html_repo_host-credentials" for service "testapp_html_repo_host" already exists
      Uploading content module "testapp_ui_deployer" in target service "testapp_html_repo_host"...
      Error uploading content module "testapp_ui_deployer" in service "testapp_html_repo_host": org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException: com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation 'Upload File': Upload application content failed { CODE: '1001' } validation error: Error while parsing request; Error: Unknown system error -122: Unknown system error -122, open 'tempFolder/KqzSHGdvwEdByT9k5S6aWYnp.zip'
      Proceeding with automatic retry... (3 of 3 attempts left)
      Service key "testapp_ui_deployer-testapp_html_repo_host-credentials" for service "testapp_html_repo_host" already exists
      Uploading content module "testapp_ui_deployer" in target service "testapp_html_repo_host"...
      Error uploading content module "testapp_ui_deployer" in service "testapp_html_repo_host": org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException: com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation 'Upload File': Upload application content failed { CODE: '1001' } validation error: Error while parsing request; Error: Unknown system error -122: Unknown system error -122, open 'tempFolder/xhnhln7K0OyZp2adj5sh1Hy3.zip'
      Proceeding with automatic retry... (2 of 3 attempts left)
      Service key "testapp_ui_deployer-testapp_html_repo_host-credentials" for service "testapp_html_repo_host" already exists
      Uploading content module "testapp_ui_deployer" in target service "testapp_html_repo_host"...
      Error uploading content module "testapp_ui_deployer" in service "testapp_html_repo_host": org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException: com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation 'Upload File': Upload application content failed { CODE: '1001' } validation error: Error while parsing request; Error: Unknown system error -122: Unknown system error -122, open 'tempFolder/amMiY0zAUIqPXQsOZvZjUk2i.zip'
      Proceeding with automatic retry... (1 of 3 attempts left)
      Service key "testapp_ui_deployer-testapp_html_repo_host-credentials" for service "testapp_html_repo_host" already exists
      Uploading content module "testapp_ui_deployer" in target service "testapp_html_repo_host"...
      Error uploading content module "testapp_ui_deployer" in service "testapp_html_repo_host": org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException: com.sap.cloud.lm.sl.xs2.content.client.ContentDeployerException: Internal server error occurred during processing of operation 'Upload File': Upload application content failed { CODE: '1001' } validation error: Error while parsing request; Error: Unknown system error -122: Unknown system error -122, open 'tempFolder/v52xYW-nDGVwq-vJQuIsSlXS.zip'
      Process failed.
      Use "cf deploy -i a76bfcd3-88f1-11eb-b412-eeee0a8a83df -a abort" to abort the process.
      Use "cf deploy -i a76bfcd3-88f1-11eb-b412-eeee0a8a83df -a retry" to retry the process.
      Use "cf dmol -i a76bfcd3-88f1-11eb-b412-eeee0a8a83df" to download the logs of the process.

       

      Thanks.

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Virender Singh Rana,

      Could you share your project structure and mta.yaml file?

      Author's profile photo Virender Singh Rana
      Virender Singh Rana

       

      mta.yaml as below:

       

      _schema-version: "3.2"
      ID: demoapp
      version: 0.0.1
      modules:
      - name: demoapp-approuter
        type: approuter.nodejs
        path: demoapp-approuter
        requires:
        - name: demoapp_html_repo_runtime
        parameters:
          disk-quota: 512M
          memory: 256M
      - name: demoapp_ui_deployer
        type: com.sap.application.content
        path: .
        requires:
        - name: demoapp_html_repo_host
          parameters:
            content-target: true
        build-parameters:
          build-result: resources
          requires:
          - artifacts:
            - HTML5Module-content.zip
            name: HTML5Module
            target-path: resources/
      - name: HTML5Module
        type: html5
        path: HTML5Module
        build-parameters:
          builder: custom
          commands:
          - npm run build
          supported-platforms: []
      resources:
      - name: demoapp_html_repo_runtime
        type: org.cloudfoundry.managed-service
        parameters:
          service: html5-apps-repo
          service-plan: app-runtime
      - name: demoapp_html_repo_host
        type: org.cloudfoundry.managed-service
        parameters:
          service: html5-apps-repo
          service-plan: app-host
      build-parameters:
        before-all:
        - builder: custom
          commands:
          - npm install
      Thanks.
      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      You project uses standalone approuter, so the project structure and mta.yaml settings would be different from what is described here.

      The following blog post might help.

       

       

      Author's profile photo Fabiano Rosa
      Fabiano Rosa

      Hi Mio,

      I'm trying to build your project (branch "hana-service") in SAP Business Application Studio, but I'm getting this error:

      Error Message:
      [npm translator] Could not locate module @sap/ui5-builder-webide-extension via resolve logic (error: Cannot find module '@sap/ui5-builder-webide-extension/package.json' from '/home/user/projects/demolaunchpad/central-launchpad-cap/app/fiori') or in a collection

      Do you have some suggestion to fix it?

       

      Regards,

      Fabiano Rosa

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Fabiano Rosa,

      Thanks for your comment.

      Have you executed the following command before build?

      cd app/fiori
      npm install
      Author's profile photo Fabiano Rosa
      Fabiano Rosa

      Hi Mio,

      With this command worked, thanks! I was executing the command "Build MTA Project" in SAP BAS, and I expected build only with this command.

      I'm also included the "npm install" in the mta.yaml, and it also worked, so you can improve your sample with it:

       - name: fiori
         type: html5
         path: app/fiori
         build-parameters:
           builder: custom
           commands:
           - npm install
           - npm run build
           supported-platforms: []

      Regards,

      Fabiano Rosa

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Your solution looks better!

      Author's profile photo Saranya Sampath
      Saranya Sampath

      Hi Mio,

       

      I followed your blog post and tried same in trial account. App is running fine from launchpad. but not getting any data. same thing happens when doing preview in Fiori app webapp/index/html

       

      Thanks

      Saranya

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Saranya,

      Thank you for your comment.

      • Is CAP service running in BAS (in the case of preview) / CF (in the case of launchpad) ?
      • Is destination "cap-launchpad" registered in your subaccount?
      • Do you see any errors in the console while running your Fiori app?
      Author's profile photo Saranya Sampath
      Saranya Sampath

      Hi Mio,

      I am running CAP service in browser during preview. destination cap-launchpad registered in subaccount.

      While running app from launchpad not getting any error. But saying no data available in service.

       

      Thanks

      Saranya

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Saranya Sampath,

       

      I have checked my project.

      It is $batch request that fetches books data. Don't you see $batch request in your app?

      Author's profile photo Meenakshi A N
      Meenakshi A N

      Hello Mio/Saranya,

      Even I am facing the same issue. Getting data while running from BAS Studio. But not in BTP HTML apps view. Destination has been created by default.

      1. No error in fiori app(Executed from HTML apps view) console and metadata loaded successfully.
      2. I checked $batch too. Status is 200 success with empty array(No data) in response
      3. It gives no data even when executed from appname-srv service

      Can someone help here

      Author's profile photo Meenakshi A N
      Meenakshi A N

      Resolved This.Tried to bind hana instance created to the application deployed in BTP manually. Post that i can see data everywhere(Launchpad,service,BTP Html app view).Posting it here so that it might help someone.

      Author's profile photo Mickey Agarwala
      Mickey Agarwala

      Hello Meenakshi,

      Can you please specify what binding you have done exactly for this. We are getting the same issue.

      Regards

      Mickey.

       

      Author's profile photo Saranya Sampath
      Saranya Sampath

      Thanks Meenakshi. Will check

       

      Thanks

      Saranya

      Author's profile photo Ankur Babu
      Ankur Babu

      Hi Mio,

      Thank you for writing this nice blog.

      Is it possible to launch this fiori app deployed on scp (btp) cloud foundry from an On-Premise Fiori launchpad tile?

      Best regards,

      Ankur

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Ankur Babu,

      Thanks for your comment.

      I haven't tried myself, but the following question seems to be relevant to your question.

      https://answers.sap.com/questions/13471399/how-to-run-sapui5-app-deployed-on-btp-scp-in-on-pr.html

      Best Regards,

      Mio

      Author's profile photo Ankur Babu
      Ankur Babu

      I posted this as a question also, still trying to make it work.

      Author's profile photo Svende Landwehrkamp
      Svende Landwehrkamp

      Hi thank you for the blog

      A question if I want to upload an Fiori Over View Page to Launchpad I still need to follow your previous blog? Because OVP does stil not support ODATA v4.

      The portal service is deprecated how do I still use the solution? I saw your blog posting "Adding a Donut Chart on top of CAP service" and want to follow it.

      Thank you, Svende

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Svende Landwehrkamp,

      Basically you can follow this blog to create an overview page on top of CAP service.

      To create OData v2 service you only need to add @sap/cds-odata-v2-adapter-proxy to your project.

      Author's profile photo Svende Landwehrkamp
      Svende Landwehrkamp

      I get this error message:

      and for v4 I get this:

      any ideas why? whould be really thankful for help.

      Author's profile photo Gregor Wolf
      Gregor Wolf

      For v4 just use http://localhost:4004/catalog. But is your CAP service running?

      Author's profile photo Svende Landwehrkamp
      Svende Landwehrkamp

      Thank you.

      Now it is kind of working after a new start just need to figure out the username and password

       

       

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      For the data source, choose "Use a Local CAP Project" instead.

      Author's profile photo sai kumar
      sai kumar

      can any one tell how to access yeoman generators

      i couldn't open it..

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Assuming you're using VS Code, make sure that you have installed Fiori tools extension pack.

      https://marketplace.visualstudio.com/items?itemName=SAPSE.sap-ux-fiori-tools-extension-pack

      Execute commend "Fiori Open Guided Development".

      Author's profile photo Benjamin Seeger
      Benjamin Seeger

      Hello Mio Yasutake,

      thank you for this blog!

      While trying out your solution with minor changes, I run into the following errors when trying to access the application in launchpad:

      1. Refused to execute script from ..../Component-preload.js because its MIME type ('') is not executable, and strict MIME type checking is enabled.
      2. Failed to load ....../Component.js 404 - Not Found

      Have you faced these issues before and know how to solve them?

      Unfortunately I did not find any solution online yet.

      Thank you in advance!

      Author's profile photo Mio Yasutake
      Mio Yasutake
      Blog Post Author

      Hi Benjamin Seeger,

      Thanks for reading!

      I haven't faced above issue. Posting question to SAP community with details (like your project structure) may help.