Safari update – Edge cases tracking without compromising UX

Tracking form submissions, pdf downloads, virtual pageviews etc, sometimes can become a bit problematic and the data collected not always accurate. That is because on some occasions the user is redirected to another page too quickly and the request to Google Analytics can’t be completed.

In these cases, workarounds have to be implemented to achieve accurate tracking. In the next few lines, I will go through two ways of doing so and specifically look into Safari.

The first method would require writing some JavaScript using the Google Analytics’s hitCallback functionality to delay the user to the destination page until the Google Analytics request is completed.
The hitCallback, is a callback function which gets called as soon as the hit has been successfully sent.

An example in the case of tracking a form would be something like the below:

// Gets a reference to the form element
var form = document.getElementById('my-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Stop the browser from submitting the form

  // Sends the event to Google Analytics first 
  ga('send', 'event', 'Signup Form', 'submit', {
    //Set timeout for 2 secs as a safety measure
    //that would allow the form to be submitted if the user blocks GA
    hitCallback: setTimeout(function() {
      //re-submit the form

Another method would be to use different transport mechanism utilising navigator.sendBeacon() which is also supported by Google Analytics’s library.
The navigator.sendBeacon() method uses the Beacon API which provides the functionality to schedule an asynchronous and non-blocking request to a web server. Beacon requests use the HTTP POST method and requests typically do not require a response. Requests are guaranteed to be initiated before a page is unloaded and they are run to completion, without requiring a blocking request.

Implementing this is quite straightforward and only requires one line to modify the Google Analytics snippet (if hardcoded):

ga('create', 'UA-XXXXX-Y', 'auto');
// Updates the tracker to use `navigator.sendBeacon`
ga('set', 'transport', 'beacon');

If Google Tag Manager is used for tracking, it is even simpler:

Which one is better?

The first method has its obvious flaws as it achieves better tracking at the cost of the user experience, but the second method up until recently was not fully supported across all browsers. Safari, in particular, had no support for the feature and the first method was the only option that worked from tracking perspective.
That time, however, is now in the past. Since the end of March, Safari support is now available for new web technologies such as Service Workers, Payment Request API, Beacon API, Subresource Integrity, improved ECMAScript 2018 support and more. The full list of new features can be seen here.

Recently I had to come up with a solution where tracking was broken on Safari and using the first method, in as slightly more complex setup, was the only option available. Generally, doing that just to satisfy an analytics tool measurement requirements is a bad practice, but if the data collected is valuable enough, it is worth it.
Going that way, however, requires a lot of checks and testing to prevent breaking website functionality so the timeout safety measure is always a good idea. There are a lot more caveats to consider, so definitely weight out the options and understand if it really makes sense to go that way.

The good news is that it looks Safari is not going to be the edge case anymore and accurate tracking can be achieved without user experience sacrifice. Still, IE to worry about, but hey, you can’t always have it all!

Share this Post

Leave a Reply

Your email address will not be published. Required fields are marked *