A quick primer on the nature of the problem
One of the most common problems I run into with Google Analytics (GA) occurs when a website uses a 3rd-party shopping cart, booking system or other transactional functionality. These systems often run on another domain, which means a user goes from xyz.com to xyz.shoppingcart.com to complete a transaction, for example. By default, GA counts this user as two sessions, assuming you have your GA tag placed on xyz.shoppingcart.com. For several reasons, this is not typically what you want. The two most important reasons are:
- User sessions are double-counted, giving you an inflated view of traffic to your website.
- The source of the user on xyz.shoppingcart.com is shown as xyz.com, or direct if you have added xyz.com to your referral exclusion list. This gives the false appearance that traffic from organic search, social media, advertising, etc. doesn’t produce conversions.
With the release of Universal Analytics in 2012, Google introduced the Linker plugin, to solve this problem. It was possible to fix before that, but much more tedious. The Linker plugin automagically transfers the GA user ID from one domain to the other, allowing GA to track visits to both domains as a single session. This works beautifully, most of the time.
Cross-domain tracking in an iFrame
One case where the Linker plugin does not work is when a 3rd-party system is delivered in an iFrame on the website domain. The Linker does not have time to do its automagical goodness on the iFrame link, because the request for the iFrame happens before the Linker has loaded.
One simple trick
Luckily, a few small modifications to Google’s sample code fix this problem. If you’ve been following along, it has probably already occurred to you: you need to add a delay to the function that sends the message event, to give the iFrame time to load. Here is a summary of the changes I made, with detailed code samples below:
- I wrapped the function that sends the message event in a setTimeout function.
- I increased the delay in the fallback createTracker function call in the iFrame code. I did this to increase the time window between when the message is sent and when the event listener gets overridden by the fallback.
Those are the important changes. Below are my code snippets with comments.
To be placed on the page that contains the iFrame:
To be placed on the page that loads in the iFrame – this is a modified version of Google’s code that includes a fallback createTracker call:
Once you are done, you can use the GA debugger Chrome add-in to see if the client ID is passing from the parent window to the child frame. When ‘create’ is called on the GA object, you should see the clientId included as a parameter. When you do, go ahead and treat yourself to a victory dance. I did.
If my solution doesn’t work in your situation, I recommend that you read through Luna Metrics’ comprehensive posts on cross-domain tracking and iFrames.