Skip to Content


Google Analytics is a great tool for tracking site usage. It gives visibility into what is getting used and when. It also has the ability to create custom reports based on filter criteria.

In this post we will show how to add Google Analytics as a Fiori Plugin that can be used to track app and page usage.


Setting up Google Analytics

Here is a link with directions on how to set up a Google Analytics (GA) Account. What we will need is the tracking ID so we can add it to the plugin. It will look like this:



Fiori Plugins

Fiori Plugins are used for customizing the UI. In our case we will use it to load and register the Google Analytics Library. We will add options to pull our tracking ID from the target mapping configuration.


Plugin Code

You can create the plugin project by creating a standard project in the WebIDE and deleting all the directories in your webapp folder until you are left with the component. It should look something like this:

The magic happens in the Component.js. The Code will show a lot of errors in the WebIDE. The errors are a mix of missing semi colons and undefined objects, both are fine and should run correctly on the launchpad.

//Load the Google Analytics library
(function(i, s, o, g, r, a, m) {
	i['GoogleAnalyticsObject'] = r;
	i[r] = i[r] || function() {
		(i[r].q = i[r].q || []).push(arguments)
	}, i[r].l = 1 * new Date();
	a = s.createElement(o), m = s.getElementsByTagName(o)[0];
	a.async = 1;
	a.src = g;
	m.parentNode.insertBefore(a, m)
})(window, document, 'script', '', 'ga');

], function(Component) {
	"use strict";

	return Component.extend("", {

		init: function() {
			//Pull the Google Analytics tracking ID from the target mapping configuration
			var sAppID = this.getComponentData().config.GA_App

			//Make sure a tracking ID is maintained
			if (sAppID) {
				//Initalize the tracker
				ga('create', sAppID, 'auto');

				//Called after the plugin is loaded
				ga('send', 'pageview', {
					'page': location.pathname + this.cleanHash(location.hash)

				//Called when the hash is changed
				$(window).hashchange(function() {
					ga('send', 'pageview', {
						'page': location.pathname + this.cleanHash(location.hash)

		cleanHash: function(sHash) {
			//Remove Guids and numbers from the hash to provide clean data
			//TODO:Remove everything between single quotes
			return sHash.replace(/((\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1})|(\d)/g,



There are a few things I’d like to make note of.

  1. Fiori is a single page application so it never changes paths. Instead, Fiori uses the hash of the URL (everything after the #) to represent a “Page”.  The hash of the URL is never sent to the server. This means that we do not see the hash in the GA Console and our data is almost meaningless. To fix this we need to concatenate the pathname and the hash into the pageview call forcing it to be sent.
  2. Fiori hashes can contain fully qualified pages for specific resources that contain identifiers in it. This is problematic if we want to see how much our pages are getting used because to GA every object will look like a different page. To fix this we strip the hash of Guids and numbers to allow for better tracking. After doing so, in GA all the pages will not have Identifiers.
  3. Another side effect of the single page architecture is that GA does not know when we change pages. To counter this we add our pageview call inside of a callback on the “hashchange” event. This means that any navigation that we make will trigger a page view to be registered inside of GA.


Registering to the Launchpad Designer

Once you have created a new project and added the code to the Component.js you need to set it up through the Fiori Launchpad Designer.  Navigate to the Launchpad Designer and create a new Target Mapping.  Keep in mind that you need to add it to a catalog that every user—or at least every user you want to track—has access to.  All you need to do is add it to the catalog; it does not need to be added to a group.  Create a new target mapping and configure it similar to what is below.

There are a few things to mention here:

  1. You must use the Semantic object of “Shell” and the Action of “plugin”
  2. Add the Google Analytics tracking code in the parameters. This allows you to edit the ID in different systems so your development system doesn’t interfere with your production data.
  3. Remember to only add the tracking code to the system you want to track.


There are a few things that this implementation might make you reconsider. Making report data meaningful might mean changing the identifiers on your apps. Also using navigation for different tabs will track the usage of the tabs themselves.

To report this post you need to login first.


You must be Logged on to comment or reply to a post.

  1. Joaquin Fornas


    I am sorry, as a beginner this blog is not clear enough for me.

    1. How do I create the project in WebIDE? Where do I link the plugin with the project I created?
    2. The magic does not work. Code has a lot of error messages, maybe because I chose the wrong project type. Could you please provide a screenshot with more steps on what to do in the WebIDE? Could you please be clearer with the code to be entered?
    3. What is service z_ga_plugin?Do I need to create a service in SICF? Where do I put the tracking ID I got in step 1?




    1. Nathan Ingram Post author

      Hey Joaquin,

      No worries! You brought up some good points that I needed to clarify.

      1. The project is the plugin. This link hopefully will help describe plugins as well as how they are used. There is no “Fiori Launchpad Plugin” project type so I just used a Master/Detail and removed all the files I did not need until it looked like the photo in the post.
      2. My Apologies. I did not point out that the errors only occur in the WebIDE the code runs fine. I have added that to the post. Also line 22 was missing a semicolon.
      3. Configuring the plugin takes place in the Launchpad Designer my example was on an ABAP system. This link should help I think. The URL that I specified is the path to the SICF node that I created when I deployed the plugin to the system. The tracking ID goes into the Parameters of the Target Mapping that you can see in the last image.


      Thanks again,


  2. Bartosz Jarkowski

    Hello Nathan,

    thanks for excellent blog!

    I tried to use this functionality, but whenever I click on any tile I’m getting following error:

    Object doesn't support property or method 'cleanHash'

    My UI5 release is: 1.48.1

    Did you encounter similar error?

    1. Nathan Ingram Post author

      Hey Bartosz,

      Thanks for pointing that out. Looks like I had a error in my refactoring 🙂

      I updated the post.  I added this


      after the hashChange callback and it fixed it.

  3. Tanveer Shaikh

    Hi Nathan,

    Thank you for such an excellent blog !!!

    Will this code in component.js will also help identify the user of the fiori application ? Can user login ids be captured in google analytics by this method ?





    1. Nathan Ingram Post author

      Hey Tanveer,


      Sorry for the late reply!

      Currently this code does not support it. I think you would have to add something like this for it to work.

      Hope this helps.


      Thanks again,



  4. Tanveer Shaikh

    Hi Nathan,

    I implemented this plugin and it works great !!!! Thanks !!

    One thing I noticed is that page titles of page views in GA are not always correct. The urls captured are always correct but sometimes Page title are not what would be expected.

    ‘Home’ is page title of Fiori launchpad home page which is correct. But when I click on tile to view some other page the changed url showing up in GA is correct but the page title is not, still shows ‘Home’.

    I tried to debug the plugin in F12 but cannot recreate the issue, while debugging always the correct page title comes up in document.title field.

    Here is an example –

    ‘Home’ Title is correct –

    Here title is incorrect –

    But sometimes titles are correct –



    1. Nathan Ingram Post author

      Hey Tanveer,


      I have not noticed this behavior. Perhaps it is caused by the GA being async? So sometimes when the event is called it is before the title has been changed.

      In our implementation we have multiple apps with the same title so we have our reporting in GA setup to use the intent to track an apps usage.

      Alternatively, I think you could look into using a different event like this one to trigger a GA call when the title changes.

      Thank again,




Leave a Reply