In this blog post I tell you how I implemented GDPR conform WebAnalytics in Fiori Launchpad (FLP).
Motivation
We created an internet portal on SAP Netweaver on-premise with FLP. The portal is not publicly available but only for invited users. After some time we expect to have about 20.000 to 35.000 users.
Of course we want to see when our users login to this portal, which devices they use, from which regions they login, which of our applications they use most, …
This is a typical use case for a WebAnalytic tool.
Requirements
I could have gone to Google Analytics or one of the other big players now, but there were a few other requirements.
The tool we would use has to be GDPR conform and it should not use cookies cause we didn’t want to show our user one of these annoying cookie banners. Another requirement was that it should run under EU law and the servers should also be located in Europe.
We had one more requirement. Cause FLP is a SPA you never leave the one and only html file (fiorilaunchpad.html). Navigation in such SPA applications is realized via # (hashes). The browser ignores everything that’s behind a hash. So this information can be used by the SPA to do fancy things like navigation e.g.
Decision
I analyzed the market for such tools. Out of the three or four tools I had a look at I chose plausible.io cause it met the above and other not explicitly mentioned requirements best.
Plausible, like most of the WebAnalytic tools, give you a script URL from their server that you have to integrate into your index.html.
In FLP applications the index.html is called fiorilaunchpad.html and this file is delivered by SAP. That means if you alter this file in your system it might be overwritten with each new version SAP delivers to their customers. Hence this is a no-go and you have to use another approach.
Implementation
In FLP the means to run your own code only once at startup is to create a FLP plugin. This is pretty much standard and well documented. But a FLP plugin is only Javascript and so I cannot integrate something like the following cause that is HTML.
<script defer data-domain="yourdomain.com" src="https://plausible.io/js/script.js"></script>
plausible.ts
To achieve this in Javascript (I used Typescript) you have to dynamically integrate the script. Here is my Typescript code.
export class Plausible {
private static TARGET_URL = 'https://plausible.io/js/script.hash.js'
private static domain_dev = 'portal-dev.mydomain.com'
private static domain_test = 'portal-test.mydomain.com'
private static domain = 'portal.mydomain.com'
injectPlausibleJS(async = 'false') {
// @ts-ignore
const ushellCfg:any = window["sap-ushell-config"]
const startUpCfg = ushellCfg.startupConfig
const system = startUpCfg.system?.toUpperCase()
// SE1, ST1 and SP1 are the system ids of the NW systems
// for Development (SE1), Test (ST1) and Prod. (SP1)
let currentDomain = Plausible.domain
switch (system) {
case 'FE1':
currentDomain = Plausible.domain_dev
break;
case 'FK1':
currentDomain = Plausible.domain_test
break;
default:
currentDomain = Plausible.domain
break;
}
const dScript = document.createElement('script');
dScript.setAttribute("src", Plausible.TARGET_URL);
dScript.setAttribute("type", "text/javascript");
dScript.setAttribute("async", async);
dScript.setAttribute("data-domain", currentDomain)
try {
document.body.appendChild(dScript);
} catch (e) {
document.getElementsByTagName('head')[0].appendChild(dScript);
}
}
}
In line 1 of the class you see that I use the plausible script https://plausible.io/js/script.hash.js
here. This script supports # navigation. Hence we see which Fiori applications our users use.
In the injectPlausibleJS
method I first retrieve the SAP system id from FLP configuration and map it to a Plausible domain.
Plausible allows to observe more than one domain even with its lowest pricing model. We use this feature to have different statistics for our develop-, test- and production-systems.
Then I create a DOM script element and set the src, type and async attributes.
Before I append this script element to the document body I set another attribute data-domain
. This is required by Plausible as you can read in the documentation.
Component.ts
To complete the code here you see the Component.ts of my plugin.
import UIComponent from "sap/ui/core/UIComponent";
import {Plausible} from './plausible/plausible'
/**
* @namespace portal.monitoring.plugin
*/
export default class Component extends UIComponent {
private plausible: Plausible = undefined
public static metadata = {
manifest: "json"
};
/**
*/
public async init(): Promise<any> {
super.init();
// inject plausible script into html
this.plausible = new Plausible()
this.plausible.injectPlausibleJS()
}
}
The end and additional infos
That’s it. Now our FLP plugin is called when FLP starts, it injects the plausible script into the HTML document and we are happy with some statistics about the usage of our portal.
Fiori Launchpad plugin development
If you don’t know how to create a FLP plugin you can e.g. have a look at this blog post which describes the details very well.