Add Google Analytics to SharePoint modern pages

I had a client requirement to help them add Google Analytics to a modern SharePoint site. The objective was to track all SharePoint page views within the site.

The first thing that came to my mind was to look for a solution available online. As this is a fairly common scenario, I assumed it would be easy to find one for my requirements. But this was also what the client had tried to do before calling us, and they got stuck with some limitations on the solutions that they have found.
There are plenty of solutions available online for using Google Analytics with SharePoint modern pages. From complete implementations, to blog posts with the relevant code snippets. But I was also unable to find one that was able to track full and partial page loads. And so I decided to tweak one to work on the scenarios.

Base solution

The code below is based on the original solution provided by João Ferreira on this blog post. He uses an SPFx application customizer to load the Google Analytics script on every SharePoint page. When testing it, we found that it was not tracking all the page loads, so we updated it slightly.

Additionally, the this.context.application.navigatedEvent event currently has a known bug and fires twice. The workaround provided by jonthenerd worked fine in this scenario.
2019-03-01 update: The bug on the navigatedEvent seems to be fixed now, so I have updated the code below. I have also sent a PR with the changes to the original repository (by João Ferreira). You can find a full implementation project on his post.

Code

The following code uses the approach provided by Google Analytics for tracking Single Page Applications, like SharePoint pages that only load partially..

Hope you fins this useful, and feel free to leave comments or provide feedback.

export default class AnalyticsApplicationCustomizer
  extends BaseApplicationCustomizer<IAnalyticsApplicationCustomizerProperties> {

  private isInitialLoad = true;

  private getFreshCurrentPage(): string {
    return window.location.pathname + window.location.search;
  }


  private navigatedEvent(): void {

    let trackingID: string = this.properties.trackingID;
    if (!trackingID) {
      Log.info(LOG_SOURCE, `${strings.MissingID}`);
    } else {

      if (this.isInitialLoad) {
        this.initialNavigatedEvent(trackingID);
        this.isInitialLoad = false;

      }
      else {
        this.partialNavigatedEvent(trackingID);
      }
    }
  }

  private initialNavigatedEvent(trackingID: string): void {

    console.log("Tracking full page load...");

    var gtagScript = document.createElement("script");
    gtagScript.type = "text/javascript";
    gtagScript.src = `https://www.googletagmanager.com/gtag/js?id=${trackingID}`;
    gtagScript.async = true;
    document.head.appendChild(gtagScript);

    eval(`
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());
          gtag('config',  '${trackingID}');
        `);
  }

  private partialNavigatedEvent(trackingID: string): void {

    console.log("Tracking partial page load...");

    eval(`
        if(ga) {
          ga('create', '${trackingID}', 'auto');
          ga('set', 'page', '${this.getFreshCurrentPage()}');
          ga('send', 'pageview');
        }
        `);
  }

  @override
  public onInit(): Promise<void> {

    this.context.application.navigatedEvent.add(this, this.navigatedEvent);

    return Promise.resolve();
  }
}

10 thoughts on “Add Google Analytics to SharePoint modern pages

  1. Hi – Do you find that this is tracking pages reliably for you? I’ve been battling this situation for a while now and had arrived at pretty much the same code as you, but I still can’t get it behaving properly because of the double-post bug (which apparently is being fixed soon, but I’m not sure when). Using your code, the first page load tracks correctly, but clicking to a 2nd page doesn’t fire at all. Clicking to a 3rd page fires the code, but the page url it tracks is for the 2nd page. After a bit of clicking around it seems to somehow catch up with itself and it starts tracking the correct urls, but the behaviour for the first few page clicks is driving me mad!

    1. Hi, yes it was working reliability when I wrote the article, so I assume it is till the case. It was tracking full and partial page loads correctly, and only one page hit was being registered, not two. I have tested the double post bug last week and it was still happening… really hope that a fix for this is available soon.

    1. Hi Rod,

      Sorry the late reply…
      I have actually never checked this, but assume so as we are injecting a scrip tag on the page so we should be able to see it. You should also be able to see the script file being downloaded on the network tag within the browser dev tools.

  2. Hello Joel,

    I’ve tried the version above and the one up to date on the repository of Joao, but none of them allow me to track partial loads on my SharePoint sites, only initial loads are working.

    Are you aware of anything like that? I can’t see which folders and subfolders are consulted the most because the partialNavigatedEvent is not triggered.

    Thanks

    1. Hi Nicolas,
      Not sure I’m afraid. All was working fine at the time I posted the script, but haven’t tested it recently.
      I believe there has been some changes since then to this.context.application.navigatedEvent, so that may be a good starting point for investigating
      Thanks for your feedback

Leave a Reply