Skip to Content
Author's profile photo Fouad Hjiyer

Google analytics in SAP Portal 7.3

As you all know portal 7.3 has an ajax framework page which means that not the whole page is reloaded but only the contentarea div. So where do you have to place your google analytic code so that every time a user visits a page/iview the data is send to google?

That’s an easy question: you have to place it somewhere in the contentarea. So the easiest way is to create an iView with your google analytic code in it and to add that iview in every page. But what if you already have a lot of iViews or pages and you do not want to go to every page and add that iView? And in some cases you only have an iView so you have to add you existed iView in a new page and also add your google analytic iview to it => overkill.

Another solution is to download the contentarea war file from your server and change the code and then overwrite SAP code. But that solution I prefer not to use in this case.

So what I did was create an iView and add it to the Ajax framework page/ custom ajax framework page and thats it!
I listen to the event “navigate” and every time that happens the data is send to google. Which means this also works for Web Page Composer(WPC) pages.

First you need to create a portal application. After you deployed it to the server you create an iView of it and then add it to the framework page you use.

You can find the source code here. After unzippen it you have to import into youre NWDS(Import > General > File system).(Don’t forget to change the google analytics id in the iview properties as explained below)

See below for the steps in detail:

Prerequisites:

Create a Google Analytics account(https://www.google.com/analytics/web/provision?et=&authuser=#provision/SignUp/)

Portal Server should be able to access(telnet) to www.google-analytics.com(check this with your basis team)

1) create a portal application

/wp-content/uploads/2013/09/create_portalapp_263167.png/wp-content/uploads/2013/09/create_portalapp_2_263177.png

Click Next > Finish.

After the application project is created you have to create an portal application object.

Right click on the portal application project you just created. Follow the next steps:

/wp-content/uploads/2013/09/create_portalapp_3_263210.png

/wp-content/uploads/2013/09/create_portalapp_4_263211.png

/wp-content/uploads/2013/09/create_portalapp_5_263212.png/wp-content/uploads/2013/09/create_portalapp_6_263213.png/wp-content/uploads/2013/09/create_portalapp_7_263214.png

After clicking Finish the portal object will be created and the googleanalytics.java file will be open in your NWDS.
The only code will put in the doContent method of the AbstractPortalComponent is:

package flexso.com;
import com.sapportals.portal.prt.component.*;
import com.sapportals.portal.prt.resource.IResource;
public class googleanalytics extends AbstractPortalComponent
{
    public void doContent(IPortalComponentRequest request, IPortalComponentResponse response)
    {
              response.include(request, request.getResource(IResource.JSP,
        "jsp/analytics.jsp"));
    }
}

(Don’t forget to add the import statement “import com.sapportals.portal.prt.resource.IResource;”)

The above code will load the jsp file that we still need to create.(see next step)

Next step is to create the JSP file where the google analytic code will be placed.

So first drilldown to the folder jsp under dist > PORTAL-INF > jsp and right click.

/wp-content/uploads/2013/09/create_portalapp_8_263218.png

/wp-content/uploads/2013/09/create_portalapp_9_263222.png

/wp-content/uploads/2013/09/create_portalapp_10_263223.png

Attention: the name that you use here has to be the same as the one you used in the doContent method in the java file.

Click Finish to proceed.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "com.sapportals.portal.prt.component.IPortalComponentRequest" %>
<%@ page import = "com.sapportals.portal.prt.component.IPortalComponentResponse" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>analytics</title>
<!-- begin part 1 -->
<%
          String googleID = componentRequest.getComponentContext().getProfile().getProperty("googleanalytics.id");
%>
<!-- end part 1 -->
<script>
// begin part 4
function callbackGetNodeInfo(currentNode){
          (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','//www.google-analytics.com/analytics.js','ga');
                    ga('create', '<%=googleID%>', 'flexso.com');
                    ga('set', 'title', currentNode.getTitle());
                    ga('set', 'location', currentNode.getNodeURI());
                    var loggindUser = LSAPI.AFPPlugin.configuration.getUser().FirstName +
                                                                      ", "          +
                                                                      LSAPI.AFPPlugin.configuration.getUser().LastName +
                                                                      " ("+
                                                                      LSAPI.AFPPlugin.configuration.getUser().LogonUid +
                                                                      ")";
                    ga('set', 'dimension1', loggindUser);
                    ga('send', 'pageview',{
                                'dimension1': loggindUser
                    });
}
// end part 4
// begin part 3
function navigationEventHandler(eventObj) {
   //eventObj.dataObject.target.split("?")[0] this will split the target at "?" and [0] will return the first part of target value which is the navurl
  if(typeof eventObj.dataObject.target === "string"){
        LSAPI.AFPPlugin.model.getNode(eventObj.dataObject.target.split("?")[0],callbackGetNodeInfo);
   }else 
        LSAPI.AFPPlugin.model.getFirstNode(callbackGetNodeInfo);
// end part 3
// begin part 2
EPCM.subscribeEvent("urn:com.sapportals:navigation", "Navigate", navigationEventHandler);//when you are navigate in the portal
EPCM.subscribeEvent("urn:com.sapportals.portal:browser","load", navigationEventHandler);//when you load the page
// end part 2
</script>
</head>
<body>
</body>
</html>

The JSP is divided in 4 parts:

Part 1: Is some java code to get the value of our google analytics id.(Which is provided by Google) This property will be maintenable through the iview property of the application. Which makes it easy when you transport the iview to acceptance or production you then only need to change the value of the property.

Part 2: Is the subscribeEvent method. With that piece of code you will run your EventHandler method every time the navigation event is triggered.

Part 3: Is the actual method that will be executed. In that method I use the getNode method of the LSAPI object. For more information about the LSAPI navigation method see the url: http://help.sap.com/saphelp_nw73/helpdata/en/c8/5eacdc37434cfb8ec5e5288b884100/frameset.htm

Part 4: Is the code that you get from google analytics. You only need to change the actual id with <%=googleID%> so it gets the value stored in the iview property. In this part I also added some additional information like user name , firstname and loginid which can be viewed in a custom report.(For more information check google analytics documentation) Attention: do not forget to change ‘flexso.com’. You can find the value that you have to put there in your google analytic piece of code that is generated by google.

The last part of the portal object is to add the property googleanalytics in the portalapp.xml.

Replace the part <component-profile/> with:

      <component-profile>
        <property name="googleanalytics.id" value="UA-XXXXX-Y">
          <property name="category" value="Google Analytics"/>
        </property>
      </component-profile>

Now the application is done and you need to deploy it to the server.

Once it deployed on the server the last step is to create an iview of it and add it to the ajax framework page you use.

Steps to follow:

Go to Content Administration > Portal Content Management > Portal Application.

/wp-content/uploads/2013/09/create_iview_from_portalapp_263304.png

Create an iview from the application by copying it to a folder in the Portal Content.

/wp-content/uploads/2013/09/create_iview_from_portalapp_2_263305.png

/wp-content/uploads/2013/09/create_iview_from_portalapp_3_263307.png

/wp-content/uploads/2013/09/create_iview_from_portalapp_4_263308.png

After you created the iview you must change the property “googleanalyticsid” in the property of the iview.

/wp-content/uploads/2013/09/create_iview_from_portalapp_5_263309.png

Click on the button “Modify Properties” and change the value with the id from google.

Do not forget to change the property “authentication scheme” to anonymous if you also want to track anonymous user on your portal.

Now you still need to add this iview to your framework page. If you use the SAP standard ajax framework page it is best to copy that page and change that one.

If you have a custom framework page just add this iview to it. If you don’t have a container for “technical/hidden iviews” make sur the iview has no tray or something visible. (Maybe you can set the height to 1px).

In this example I will add the iview to standard framework.

You can find the standard SAP Ajax Framework page under: Portal Content > Portal Users > Standard Portal Users > Ajax Framework Content.

/wp-content/uploads/2013/09/add_iview_to_frameworkpage_263314.png

Open the page and select youre google analytic iview and right click on it and select Add iview to page > Delta link.

/wp-content/uploads/2013/09/add_iview_to_frameworkpage_2_263315.png

The last step is to change the container where the iview will be placed.

/wp-content/uploads/2013/09/add_iview_to_frameworkpage_3_263316.png

Now save your changes and go to your google account do some tests.

PS: this is my first blog.

Enjoy!

Assigned tags

      31 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi,

      I like this blog and tried to implement the same by following the steps mentioned in this blog. But, I found that the data is not sending to my Google account.

      I have created a google account and generated Google Analitics ID and used the same in the application code.

      I wuld be greatful to you, if you let me know what would I missed and where.

      Thank you,

      Rambabu

      (ramkancharla003@gmail.com)

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Rambabu,

      First I need to say that I posted an url to source code of my application but the javascript code in the jsp is not the same as the one posted in the blog. The one in the jsp code is outdated(Copy paste the one from the blog). I still need to change it, I will try to change it later on today.

      But to answer to your question it can be different things.

      The first thing to check is if the data is send to google. You can do that with fiddler. It's a tool to trace your http request (http://fiddler2.com). Normally you should see google-analytics in there.

      If it's not the case you need to check if you don't have any javascript errors. That you can do by pressing F12 in your browser.(Chrome > tab console, IE > tab script)

      What you also need to check is the permission of the iview. Like I mentioned in the blog.

      I hope this helps if not just send me an email with your source code so I can check it.

      Good luck!

      Kind Regards,

      Fouad

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

      Thank you for all your help.

      Please give me your email id so that I will send you the source code, here is my email id: rambabu.kancharla@nttdata.com


      Thank you.

      Regards,

      Rambabu

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

      Would you please help me to resolve my issue?

      I tried all the options and no script errors, but the data is not sending to account.

      Regards,

      Rambabu

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

      Thanks For Sharing 🙂 🙂 ,  I will Implement today and check it once this is really new Concept and you explained with screen shots makes me to develop on my own 😉 😉 , Thank u  once again for Sharing 🙂 🙂 🙂

      Regards,

      Giri

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Giri,

      Good luck!

      I added some prerequisites in the blog.

      Just for your information:

      The problem for Rambabu was that the server had no access to Google analytics.

      Kind Regards,

      Fouad

      Author's profile photo Noël Hendrikx
      Noël Hendrikx

      Hi Fouad,

      Nice blog, will try this soon. Instead of navigating with navurl, does this support navigation by quicklinks as well?

      Cheers,

      Noël

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Noël,

      Good question!

      I don’t think this will work because what a quicklink actually does is refreshing the whole page and go to the iView/page from that quicklink so it is not triggered by the doNavigate method.

      This can be a problem because this means that the data will be send to google through this code:

      1. EPCM.subscribeEvent("urn:com.sapportals.portal:browser","load", navigationEventHandler);//when you load the page

      Which means it will send the firstpage from your portal which is not correct.


      But you have different options to solve this:

      The first one is very easy and is to check if you’re accessing the portal with a quicklink or not. This can be done by checking the url path in your javascript code

      1. document.location.pathname if its equal to “/irj/portal” then no quicklink is used but I’m not 100% sure if this is right in every case. And also you will not have access to the title name of the page.

      Second option (note that we did this in a custom framework but should also work in the standard framework): What we did in a project of ours, we didn't used quicklinks(because the refreshing of the page was annoying for the customer) but we created a mechanism through the window.onhashchange function. The benefit of this is that not the whole page is reloaded.

      So how did we do that:

      http://<host>:<port>/irj/portal#Content Administrator/Portal Display

      So when a user cliks on a link that point to the above url the onhashchange function will be triggered from there we collect some data and pass it to the donavigate method which will then trigger our google analytics code.

      I hope this is an answer to your question and that you have enough information to implement it.

      Kind Regards,

      Fouad

      Author's profile photo Noël Hendrikx
      Noël Hendrikx

      Thanks for your solution! The link is still user friendly, that's one of my main concerns of the navurl or navigationtarget=. But will your link work also from outside the portal? As an example, when the user bookmarks the Portal Display page as you mentioned, does analytics trigger this?

      Also can you send parameters to a portal page with the # tag? I think that will be a side effect, right?

      Fortunately I am writing my own framework, so I will add on every page a js link to analytics (just like in the old days 🙂 ).

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Noël,

      That's right the quicklink is user friendly but the only problem for us was that the content editor didn't had access to the pcd which means he couldn't know which quicklinks existed. With the way we work he can just follow the navigation and create his own link to every page.(Off course he needs to be careful, the page he wants to point to needs to be in a role the user have. But that's the same for quicklinks. And another disadvantage of my way of working is that the url has to be correctly the same so Content Administration > Portal Display has to be #Content Administration/Portal Display with spaces etc...)

      I'm not sure but I think we added some piece of code in our javascript to check if the window.location.hash is empty or not. We did it in this part of code:

      EPCM.subscribeEventReliable('urn:com.sapportals:navigation', 'AFPisLoaded', onAfpIsLoaded);

      And if it exists then the doNavigate method is triggerd which means or google analytics code is triggered.

      So normally if a user has a bookmark to the Portal Display it should trigger the analytics code.

      Either way you did some good thinking!

      Kind Regards,

      Fouad

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

      Big Wow! I understand how much time you have spend for this blog.

      Keep up the good work! 🙂

      Advanced New Year 2014 Wishes! 🙂

      Regards,

      Hari Suseelan

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Hari Suseelan,

      Thanks 😉 !

      A happy new year and a good health to you!

      Kind Regards,

      Fouad

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

      Thanks! Wish you the same!

      All the best! 🙂

      Regards,

      Hari Suseelan

      Author's profile photo Shreyas Pandya
      Shreyas Pandya

      Hi Fouad,


      Simply genius work.


      Regards,

      Shreyas Pandya

      Author's profile photo Vera Gutbrod
      Vera Gutbrod

      Hi Fouad!

      Exceptional blog. You will be rewarded for this from the SAP Portal team. Wait for further announcements in the next days.

      Regards

      Vera

      SAP Portal Product Management Team

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi everyone,

      I would like to thank you for voting for me!

      This motivate's me to write new blogs.

      Kind Regards,

      Fouad

      Author's profile photo Former Member
      Former Member

      This is an outstanding blog posting and really useful information to share - thank you very much.

      Gareth.

      Author's profile photo Vera Gutbrod
      Vera Gutbrod

      Hi Fouad!

      Your blog won in the 2013 SAP Portal Top Blog campaign. Congratulations to you. More information in this blog http://scn.sap.com/community/netweaver-portal/blog/2014/01/30/sap-portal-top-blog-2013-and-the-winner-is and there are also more rewards for you to come.

      Regards and thanks

      Vera

      Author's profile photo Vincent Noiset
      Vincent Noiset

      Hello,

      we intended to use Google Analytics for page statistics.  But not all user have internet access...

      Did you try to get statistics (on iView, Page,...) with the SAP Standard service that is Activity Data Collector ?

      Best regards.

      Vincent

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Vincent,

      Yes we use it sometimes it depends on what the customer wants. If it's only to show basic data you can use the standard reporting iViews from SAP.(You probably know that)

      But sometimes that is not enough so we write a custom(java) application that will read the tracefiles and do something with it. That application will run everyday and once its done it will archive the trace file so only the trace file of the current day will be treated. Most of the time we write the data from the trace file into a database and then a report is made of that data.(We also read kmActivity trace file, with this information you can see which a document has been read by a which user, or get statistics like top 10 documents,...)

      You know that when you activate the Activity Data Collector trace files will be created on the server I think the default path is /server{N}/portalActivity and /server{N}/kmActivity I don't have access to a portal now so I'm not 100% sure and of course you can change the folder where the trace files will be saved.

      I hope this is an answer to your question. If not just let me know.

      Kind Regards,

      Fouad

      Author's profile photo Joelle Wilson
      Joelle Wilson

      Fouad,

      Thank you for the great detail on implementing in 7.3!      I am wondering if you have information about adding Google Analytics to prior versions?  Specifically we are running 7.02 and would like to implement on our current system.

      Thank you,

      Joelle

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Joelle,

      Sorry for my late response.

      But for the previous versions of the portal there is a good documentation online. Where they explain step by step what to do:

      http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/50b94044-7008-2b10-1680-c04e4526367b?overridelayout=true

      I hope that this is what you asked for.

      Good luck!

      Kind Regards,

      Fouad

      Author's profile photo Joelle Wilson
      Joelle Wilson

      Thank you, Fouad.   This appears to be what I need!

      Appreciate your time,

      Joelle

      Author's profile photo Former Member
      Former Member

      Hi Fouad, I need to know if this solution works in Portal 7.4.

      Thanks and regards.

      Author's profile photo Fouad Hjiyer
      Fouad Hjiyer
      Blog Post Author

      Hi Sebastian,

      Sorry for the late response.

      I did not had the chance yet to work with a portal 7.4. But that's something that you can easily check. If you open the console in the browser(F12) after accessing the url of the portal you can type EPCM and see if the object exists.

      If that is the case you can try to copy paste the following in the console.

      function navigationEventHandler(eventObj) { 

        alert("navigation works as before");

      }  

      EPCM.subscribeEvent("urn:com.sapportals:navigation", "Navigate", navigationEventHandler);

      EPCM.subscribeEvent("urn:com.sapportals.portal:browser","load", navigationEventHandler);

      If it there is no error you can try to navigate in the portal and an alert should be shown.

      It is also possible that the EPCM object is not available and that you will need to put a breakpoint in a random js script from SAP where it is available.

      Hope this helps. Again I could not test this so it is possible that it does not work and then you should try to implement the whole solution as described in the blog.

      Kind Regards,

      Fouad

      Author's profile photo Former Member
      Former Member

      Hi Sebastian,

       

      Did you tried, is it working for Portal 7.4 & higher?

       

      Thanks & best Regards,

       

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

       

      Does this solution works for SAP Portal 7.4 & higher?

       

      Thanks,

      NS

       

      Author's profile photo Former Member
      Former Member

      Hi Fouad,

       

      Thanks for excellent blog!!

       

      I am getting compiler error in analytics.jsp

      Error message: componentRequest cannot be resolved.

       

      Thanks

      Maha

       

       

      Author's profile photo Prasad
      Prasad

      Hi Mahboob,

      Can you please let us know answer for your query. Hope it has been resolved by you now?

      Also the GA website tracking code that is generated for us is differeint to that mentioned in previous blogs.

      Can you please provide us the code of your .jsp file?

      <script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxx"></script>
      <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'UA-xxxxxxx-1');
      </script>

      We have created the GA userid and have provided the information for the tracking code. Is anything else required in Admin to see the report in the GA account?

      Send test traffic is working fine.

       

      Thanks & Regards,

      Prasad.

      Author's profile photo ram mishra
      ram mishra

      Hi Fouad,

      Can you please help me to set up Google analytics on 7.0 SP29 version.

      I have gone through the document shared by you in previous comment but it is not very clear about the PAR file development.

       

      Thanks and Regards

      Ram Krishna Mishra

      Author's profile photo Vara Prasad Kodati
      Vara Prasad Kodati

      Hi Fouad,

      we have the same requirement to integrate Google analytics iview in portal and I am following this blog. I am not clear what exactly  to change in analytics.jsp file.

       

      Please help me in this.

       

      Thanks in advance

      Regards,

      Vara Prasad