Skip to Content

Google Analytics for Fiori Launchpad

Introduction

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:

'UA-XXXXXXXX-1'

 

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', 'https://www.google-analytics.com/analytics.js', 'ga');

sap.ui.define([
	"sap/ui/core/Component"
], function(Component) {
	"use strict";

	return Component.extend("com.ipaper.ca.ga.plugin.Component", {

		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)
					});
				}.bind(this));
			}
		},

		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.

Considerations

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.

17 Comments
You must be Logged on to comment or reply to a post.
  • Hello

    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?

    Thanks

    Joaquin

     

    • 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,

      Nathan

  • 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?

    • Hey Bartosz,

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

      I updated the post.  I added this

      .bind(this)

      after the hashChange callback and it fixed it.

  • 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 ?

    Thanks,

    Tanveer

     

     

    • Hey Tanveer,

      Thanks!

      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,

      Nathan

       

  • 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 –

    Thanks,

    Tanveer

    • 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,

      Nathan

       

  • Hi Nathan,

    I’ve successfully managed to integrate this set up, but am having a similar issue with integrating the Tag Manager snippet of code into the launchpad as well. Do you have any guidance on how to go about that?

  • Hi Nathan,

    Nice blog!Thanks for providing such information.

    I am able to see Active users with specific page details and now will explore to get user names.

    Active user count decrease if you do not perform any action within 1 min at the same time app is open in launchpad.Could you please provide information for such behavior?

     

  • Hi Nathan,

    I have some doubts we are planning to implement GA to our fiori lanchpad, we are running on fiori 2.0 & ui5 version 1.48.1…can we implement your code …?

    Second doubt is in 2 point you have mentioned fiori plugin …I think its nothing but custom “ZXXX” application that we created through WebIDE …? Do we need to install any other plugin..?

    After exporting our custom app do we need export to any particular package..like  /sap/bc/ui5_ui?  After that do we need to activate any ICF nodes or Odata services..?

     

    Thanks & regards

    nandish

  • Thank you for your valuable post, offering data tracking!
    I assume using GA in fact means that data get posted to Google servers. What about data privacy when having sensitive data or the need to protect such?
    Can there be away to lock/encrypt data in a reasonable manner to reflect such needs?

  • Hi Nathan Ingram,

    This is really awesome blog.

    I am also trying to integrate Google Analytics tool. I have got below generated code. How can I fit this in my case? Can you please guide me? I am feeling difficulty to integrate.

     

    <!– Global site tag (gtag.js) – Google Analytics –>
    <script async src=”https://www.googletagmanager.com/gtag/js?id=UA-XXXXXX-1″></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag(‘js’, new Date());

    gtag(‘config’, ‘UA-XXXXXX-1);
    </script>

    Thanks and Regards,

    RK

    • Hi Ram Mishra,

      You need to paste that script in your index.html file. Keep in mind that this only retrieves the scrips needed from the google server.

      Add the following code into the init method of your controller; 

      ga(‘send’, ‘pageview’, ‘/YourAppName’);

      This will use the scripts that were loaded from the index.html to send detailed information to Google Analytics.

      Kind regards,

      Vincent

  • Thanks Vincent for your reply.

    Shall I follow this approach for plugin or I have do this for individual Apps.

     

    Thanks and Regards,

    RK