Skip to Content
Technical Articles

XSA Fiori Launchpad On-Premise Configuration With Cross-MTA Dependencies and UAA.

If you have read a couple of my previous blogs you will be able to follow my journey configuring the Fiori Launchapd on XSA. This most recent post presents what I feel is the ideal configuration, allowing the use of multiple MTA’s for your applications while retaining UAA support.

If you have been trying to setup a Fiori Launchpad on XSA, I am sure you are familiar with the official SAP documentation in the following link: https://help.sap.com/viewer/4505d0bdaf4948449b7f7379d24d0f0d/2.0.04/en-US/8a583342d1c64822837fe49efbafdb53.html

While much of the information is present in the documentation, I feel the instructions are incomplete and unclear.

I have a working sample configuration prepared and available in my github: https://github.com/bigsmity/xsalaunchpaddemo

“launchpaddemoapp2” is where all the magic happens for this blog. I have left the previous configurations available even though they are now obsolete.

The main difference is the change from using the @sap/approuter to using @sap/site-app-server. At the time of writing no working templates appear to exist in the public domain for this configuration.

With this setup, you only need to write config in the MTA of the UI5 application. This implementation is independent of the launchpad configuration.

Let’s get into it.

 

UI5 Application Setup

Create a new MTA called “launchpaddemoapp2” and add a SAPUI5 HTML5 Module called “launchpaddemoapp2_ui”.

 

Create a folder called “site” directly in the UI5 module folder.

 

Create a file called “site-content.json” in the “site” folder you just created.

 

Your folder structure should look as follows:

 

Paste in the example site-content.json content from the SAP provided documentation as a starting point. Please note the source provided in the official documentation is missing the last closing bracket ‘}’. There is also a leading space in the group Id field. Both of these have been corrected in the snippet below

site-content.json Starting point (corrected from SAP documentation)

{
  "roles": {
   "Everyone": {
     "_version": "1.0",
     "identification": {
            "id": "Everyone",
            "namespace": "",
            "entityType": "role"
     },
     "payload": {
            "catalogs": [],
            "groups": [{
                              "id": "MyGroupId"
             }]
     }
   }
  },
  "applications": {
  },
  "groups": {
   "MyGroupId": {
     "identification": {
      "id": "MyGroupId",
      "i18n": "i18n/i18n.properties",
      "namespace": "",
      "title": "{{ MyGroupId_GROUP_TITLE}}"
     },
     "payload": {
      "tiles": [{
        "id": "SampleTile",
        "subTitle": "{{SampleTile_SUB_TITLE}}",
        "appId": "MyUniqueAppID",
        "target": {
         "semanticObject": "myApp",
         "action": "show",
         "parameters": []
        }
      }]
     }
   }
  }
}

 

 

Update the site-content.json with your Group, Tile and Application configuration

site-content.json complete, configured

{
	"roles": {
		"Everyone": {
			"_version": "1.0",
			"identification": {
				"id": "Everyone",
				"namespace": "",
				"entityType": "role"
			},
			"payload": {
				"catalogs": [],
				"groups": [{
					"id": "launchpaddemoapp2_ui_GroupId"
				}]
			}
		}
	},
	"applications": {

		"launchpaddemoapp2_ui": {
			"sap.app": {
				"_version": "1.3.0",
				"id": "launchpaddemoapp2_ui",
				"title": "Launchpad Demo App2",
				"i18n": "i18n/i18n.properties",
				"tags": {
					"keywords": []
				},
				"crossNavigation": {
					"inbounds": {
						"launchpaddemoapp2_uiShow": {
							"semanticObject": "launchpaddemoapp2_ui",
							"action": "show",
							"deviceTypes": {
								"desktop": true,
								"tablet": true,
								"phone": true
							},
							"signature": {
								"parameters": {},
								"additionalParameters": "allowed"
							}
						}
					},
					"outbounds": {}
				}
			},
			"sap.ui": {
				"_version": "1.3.0",
				"technology": "UI5"
			},
			"sap.ui5": {
				"componentName": "launchpaddemoapp2_ui",
				"_version": "1.2.0"
			},
			"sap.platform.runtime": {
				"componentProperties": {
					"url": "/"
				}
			}
		}

	},
	"groups": {
		"launchpaddemoapp2_ui_GroupId": {
			"identification": {
				"id": "launchpaddemoapp2_ui_GroupId",
				"i18n": "i18n/i18n.properties",
				"namespace": "",
				"title": "Launchpad Demo App"
			},
			"payload": {
				"tiles": [{
					"id": "launchpaddemoapp2_ui_tile",
					"title": "Launchpad Demo App2",
					"subTitle": "launchpad demo app2",
					"icon": "sap-icon://share-2",
					"appId": "launchpaddemoapp2_ui",
					"target": {
						"semanticObject": "launchpaddemoapp2_ui",
						"action": "show",
						"parameters": []
					}
				}]
			}
		}
	}
}

 

 

Update the manifest.json and add the cross navigation settings to the “sap.app” section

"crossNavigation": {
			"inbounds": {
				"launchpaddemoapp2_uiShow": {
					"title": "Launchpad Demo App2",
					"icon": "sap-icon://share-2",
					"semanticObject": "launchpaddemoapp2_ui",
					"action": "show",
					"deviceTypes": {
						"desktop": true,
						"tablet": true,
						"phone": true
					}
				}
			},
			"outbounds": {}
		}

 

Update the manifest.json and add the component properties to the root level object.

"sap.platform.cf": {},
	"sap.platform.runtime": {
		"componentProperties": {
			"url": "/resources/webapp"
		}
	}

 

Update the manifest.json file to add the component name to the “sap.ui5” object

"componentName": "launchpaddemoapp2_ui",

 

manifest.json complete, configured

{
	"_version": "1.1.0",
	"sap.app": {
		"_version": "1.1.0",
		"id": "launchpaddemoapp2_ui",
		"type": "application",
		"i18n": "i18n/i18n.properties",
		"applicationVersion": {
			"version": "1.0.0"
		},
		"title": "{{appTitle}}",
		"description": "{{appDescription}}",
		"ach": "ach",
		"sourceTemplate": {
			"id": "hanatemplates.basicSAPUI5ApplicationProject",
			"version": "0.0.0"
		},
		"crossNavigation": {
			"inbounds": {
				"launchpaddemoapp2_uiShow": {
					"title": "Launchpad Demo App2",
					"icon": "sap-icon://share-2",
					"semanticObject": "launchpaddemoapp2_ui",
					"action": "show",
					"deviceTypes": {
						"desktop": true,
						"tablet": true,
						"phone": true
					}
				}
			},
			"outbounds": {}
		},
		"dataSources": {
			"appDataSource": {
				"uri": "launchpaddemoapp2_js_dest/xsodata/APP_DATA.xsodata/",
				"type": "OData",
				"settings": {
					"odataVersion": "2.0"
				}
			}
		}

	},

	"sap.ui": {
		"_version": "1.1.0",
		"technology": "UI5",
		"icons": {
			"icon": "",
			"favIcon": "",
			"phone": "",
			"phone@2": "",
			"tablet": "",
			"tablet@2": ""
		},
		"deviceTypes": {
			"desktop": true,
			"tablet": true,
			"phone": true
		},
		"supportedThemes": [
			"sap_hcb",
			"sap_bluecrystal"
		]
	},

	"sap.ui5": {
		"_version": "1.1.0",
		"componentName": "launchpaddemoapp2_ui",
		"rootView": {
			"viewName": "launchpaddemoapp2_ui.view.View1",
			"type": "XML"
		},
		"dependencies": {
			"minUI5Version": "1.30.0",
			"libs": {
				"sap.ui.core": {},
				"sap.m": {},
				"sap.ui.layout": {},
				"sap.ushell": {},
				"sap.collaboration": {},
				"sap.ui.comp": {},
				"sap.uxap": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "launchpaddemoapp2_ui.i18n.i18n"
				}
			},
			"app_data": {
				"dataSource": "appDataSource"
			}
		},
		"resources": {
			"css": [{
				"uri": "/css/style.css"
			}]
		},
		"routing": {
			"config": {
				"routerClass": "sap.m.routing.Router",
				"viewType": "XML",
				"async": true,
				"viewPath": "launchpaddemoapp2_ui.view",
				"controlAggregation": "pages",
				"controlId": "idAppControl"
			},
			"routes": [{
				"name": "RouteView1",
				"pattern": "RouteView1",
				"target": ["TargetView1"]
			}],
			"targets": {
				"TargetView1": {
					"viewType": "XML",
					"transition": "slide",
					"clearAggregation": true,
					"viewName": "View1"
				}
			}
		}
	},
	"sap.platform.cf": {},
	"sap.platform.runtime": {
		"componentProperties": {
			"url": "/resources/webapp"
		}
	}
}

 

Open the package.json file, you will see the following approuter configuration:

{
	"name": "launchpaddemoapp2_ui-approuter",
	"engines": {
		"node": ">=4.0.0 <9.0.0"
	},
	"dependencies": {
		"@sap/approuter": "6.1.0"
	},
	"scripts": {
		"start": "node node_modules/@sap/approuter/approuter.js"
	}
}

We will need to replace this with a site-app-server configuration:

{
	"name": "launchpaddemoapp2_ui",
	"engines": {
		"node": ">=4.0.0 <9.0.0"
	},
	"dependencies": {
		"@sap/site-app-server": "^1.9.x"

	},
	"scripts": {
		"start": "node node_modules/@sap/site-app-server/index.js"
	}
}

 

Open the xs-app.json file, enable UAA and add the standard route

{
	"welcomeFile": "webapp/index.html",
	"authenticationMethod": "route",
	"routes": [{
		"source": "^/(.*)$",
		"localDir": "resources/webapp"
	}]
}

 

Open the mta.yaml file and add the reference to the target Fiori Launchpad

 - name: flp-launchpaddemoapp2-client
   type: com.sap.portal.site-content
   parameters:
      config:
        siteId : launchpaddemo

The siteId property is the ID value of the mta.yaml containing the Fiori Launchpad

 

Add the requires reference to the UI5 application

 - name: launchpaddemoapp2_ui
   type: html5
   path: ui
   requires:
    - name: flp-launchpaddemoapp2-client
    - name: launchpaddemoapp2_uaa
    - name: launchpaddemoapp2_js_api
      group: destinations
      properties:
        name: launchpaddemoapp2_js_dest
        url: '~{url}'
        forwardAuthToken: true

 

mta.yaml complete, configured

ID: launchpaddemoapp2
_schema-version: '2.1'
version: 0.0.1

modules:
 - name: launchpaddemoapp2_db
   type: hdb
   path: db
   properties:
      SAP_JWT_TRUST_ACL:
        - clientid: '*'
          identityzone: '*'
   requires:
    - name: launchpaddemoapp2_uaa
    - name: hdi_launchpaddemoapp2_db
      properties:
        TARGET_CONTAINER: '~{hdi-container-name}'


 - name: launchpaddemoapp2_js
   type: nodejs
   path: js
   properties:
     CORS:
       - uriPattern: .
         allowedMethods:
           - GET
           - POST
         allowedOrigin:
           - host: '*'
     SAP_JWT_TRUST_ACL: 
       - clientid: '*'
         identityzone: '*' 
   provides:
    - name: launchpaddemoapp2_js_api
      public: true
      properties:
         url: ${default-url}
   requires:
    - name: launchpaddemoapp2_uaa
    - name: hdi_launchpaddemoapp2_db
    - name: launchpaddemoapp2_db
    
    


 - name: launchpaddemoapp2_ui
   type: html5
   path: ui
   properties:
     CORS:
       - uriPattern: .
         allowedMethods:
           - GET
           - POST
         allowedOrigin:
           - host: '*'
     SAP_JWT_TRUST_ACL: 
       - clientid: '*'
         identityzone: '*' 
   requires:
    - name: flp-launchpaddemoapp2-client
    - name: launchpaddemoapp2_uaa
    - name: launchpaddemoapp2_js_api
      group: destinations
      properties:
        name: launchpaddemoapp2_js_dest
        url: '~{url}'
        forwardAuthToken: true



resources:
 - name: hdi_launchpaddemoapp2_db
   properties:
      hdi-container-name: ${service-name}
   type: com.sap.xs.hdi-container

 - name: launchpaddemoapp2_uaa
   parameters:
      service: xsuaa
      service-plan: space
   type: com.sap.xs.uaa
   
 - name: flp-launchpaddemoapp2-client
   type: com.sap.portal.site-content
   parameters:
      config:
        siteId : launchpaddemo

 

Build and deploy your application, then run your launchpad.

 

The group and Tile can now be seen.

 

Click the Tile to launch the UI5 application.

 

There you have it, you now have a correctly configured Fiori Launchpad! Tiles are self contained, and UAA is available!

 

It should be noted when using the site-app-server, you lose the ability to run the UI5 application in the workspace context. My current solution is to modify the package.json file when developing in Web IDE:

{
	"name": "launchpaddemoapp2_ui",
	"engines": {
		"node": ">=4.0.0 <9.0.0"
	},
	"dependencies": {
		"@sap/site-app-server": "^1.9.x",
		"@sap/approuter": "6.1.0"

	},
	"scripts": {
		"start": "node node_modules/@sap/site-app-server/index.js",
		"dontstart": "node node_modules/@sap/approuter/approuter.js"
	}
}

I keep the dependency for both node modules, but switch the name of the start script from “start” to “dontstart”.

8 Comments
You must be Logged on to comment or reply to a post.
  • Hi Bradley,

    Thank you for your very informative samples and explanation. With your help I have manage to setup my own fiori launchpad with its tiles. However, I have lucked out on the roles part. If i set the roles to Everyone, the tiles are displayed but if assigned to a certain roles, it goes missing. Any idea on how we can control tile display on the fiori launchpad ? Have you had success on role level control at fiori launchpad either displaying the tile or launching the tile application.

    i raised the question in the community as well.

    https://answers.sap.com/questions/13048624/xsa-fiori-launchpad-not-displaying-application-til.html

    Hope you can help or give some hints or even how to trace it. Your help is greatly appreciated.

    Thanks.

    Anand

    • Hi Anand,

      I am glad you have found my blog useful. I have configured the tile visibility successfully in the past and have replied directly to your question with some details that should help.

      Thanks,

      Brad.

  • Hi Bradley,

    This is great stuff!

    Your example works perfectly. But I have problems adapting this to our existing development. Would you have any ideas, why would an additional/second MTA would replace portal service content with its site-content.json entirely instead of merging it with the existing site content in the portal service? I seem to be following the example to the letter.

    Sigitas

    • Hi Sigitas,

      I am glad my blog has helped! I have seen this issue before, and the cause in my case was quite strange.

      Do you have more than one i18n.properties file in your ui5 app? When I removed all my language variants i18n_en and i18n_en_US etc leaving only the base i18n.properies file the launchpad returned to normal.

      let me know if that works.

      Thanks,

      Brad.

      • Hey, Bradley,

        Your suggestion to look into i18n.properies was spot on!

        Though I did not go to the very bottom of this. But it seems the request header Accept-Language acts as a sort of selection/filtering criterion as to which site content will be served (well.. kinda obvious once you know it 🙂 ). Accept-Language: * will show the complete merged set with texts from i18n.properies file. But whenever some specific language is requested and the language is missing or especially if it is just partially present then this will definitely produce some unexpected results.

        Specifying several languages along with their priorities in Accept-Language does not seem to have an effect. It is only the first language that is used.

        So I guess the safe bet is to either have just the i18n.properties or makes sure to include the same set of languages in i18n_*.properties files in every component involved.

        Thanks!

        Sigitas

  • Hi Bradley,

    If i Follow the above steps, will the Fiori Launchpad also come, or we have to follow the steps in your other blog to get the FLP running. ?

     

    Thanks,

    Mudit

    • Hi Mudit,

      These steps will allow you to add your ui5 application to any existing FLP.

      If you do not have a launchpad already, a new FLP created straight from the template in webide will work for you.

      Thanks,

      Bradley.