Cross-domain tracking isn’t the easiest thing to implement, though. At its easiest, especially if you use Google Tag Manager, it’s a question of configuring a couple of fields in your Google Analytics trackers and snippets. However, issues typically arise when your website uses unconventional link redirects, or when you want to persist the Client ID in an iframe loaded from another domain.
In this article, I thought I’d provide a short checklist to go through when issues with cross-domain tracking arise.
How to test if cross-domain tracking is working
If cross-domain tracking is working, all traffic from one domain to another should be part of the same session, and thus attributed to the same Source / Medium dimensions.
You should not use Google Analytics’ Real Time Reports to analyze the cross-domain pattern! Real Time Reports show each hit only with the dimensions and parameters carried by the hit itself. This means that you won’t be able to debug session-scoped stuff like Source and Medium using only what you see in the Real Time Reports.
In other words, you’ll need to wait for the hits to populate in the standard reports.
The easiest way to verify if cross-domain tracking is working in Google Analytics, is to browse to the first domain using custom UTM parameters, for example:
Then, while still browsing the first domain, click a link or open a page with the iframe to the second domain.
After this is done, in the Google Analytics View which shows data from both domains, you can apply a segment to only include your custom campaign traffic:
Once the data hits the Google Analytics reports, you should find your single session when applying the segment. After that, go to the Behavior > Site Content > All Pages report. If cross-domain tracking is working properly, you should see both the pageview(s) from the source domain and the pageview(s) from the target domain in the report.
If cross-domain tracking isn’t working, you’ll only see the pageview(s) from the source domain. The following checklist should help in this case.
For cross-domain tracking to work on your website and Google Analytics Property, the following things need to all be in place.
- All domains included in cross-domain tracking must collect data to the same Google Analytics Property – Jump to details
- All domains that are the source of cross-domain traffic, i.e. the traffic departs from these domains, need to be in the Referral Exclusion List of the Google Analytics Property settings – Jump to details
- When entering the target domain via a link in the source domain or an iframe, the URL of the page loaded in the web browser must have the _ga=1.234567.234567.234567 URL query parameter in place – Jump to details
- Any Google Analytics trackers or tags firing on the target domain need to have the allowLinker field set to true – Jump to details
These are the four basic steps you need to make cross-domain tracking work on your site. Note that steps (3) and (4) have complicated workarounds for when query parameters or the linker plugin won’t work, but in the majority of cases these four steps are enough.
In the following chapters, I’ll examine each step in more detail.
A Property in Google Analytics is a tracking configuration that collects data from your digital applications such as your website. Each Property in Google Analytics has a unique identifier, known as the Tracking ID:
Every Property has its own table of data, which comprises all the hits that are sent to that particular Property. Thus, each Property has its own users, sessions, and aggregation buckets, and these data sets are unique to each Property.
Because of this, it’s important that when you collect cross-domain traffic across two separate domains, both domains will need to collect data to the same Google Analytics Property. There is no such thing as cross-domain traffic across Google Analytics properties, and the only way to even approach something like that would be to utilize the Roll-up Reporting feature of Google Analytics Premium.
Universal Analytics starts a new session whenever a new referral is detected as a traffic source. Thus, if you first enter a site via Google’s organic search (google / organic), and then follow a cross-domain link from the source domain to the target domain, the target domain hit would be recorded as having originated from sourceDomain.com / referral, marking the start of a new session. And this is even if you have cross-domain tracking otherwise in place!
By utilizing the Referral Exclusion List, you’re telling Google Analytics to disregard referral traffic from the source domain, and to treat it as Direct traffic instead. Universal Analytics relies on Direct traffic for campaign attribution as well as session stitching. Each hit in the session, after the initial acquisition, is actually a “Direct” hit, and this is how Google Analytics knows that the session should still be kept alive.
So, Referral Exclusion List keeps the traffic from the source domain to the target domain part of the same session, which is crucial for you to make sense of cross-domain traffic. Thus make sure that you have all the possible source domains, i.e. domains that send traffic to other domains, in the Referral Exclusion List of your Google Analytics property settings.
As I said in the very beginning of this article, Google Analytics relies on the Client ID to assign hits to specific sessions and users. The Client ID is stored in a browser cookie named _ga, which is, by default, written on the highest possible domain name the website has access to. On my website, for example, the _ga cookie would be written on simoahava.com, and thus it is available to simoahava.com and all its possible subdomains.
When you move from domain to domain, this Client ID needs to somehow travel with the user, but due to the restrictions of the web browsers’ same-origin policy, the target domain cannot simply fetch the cookie written on the source domain.
For this reason, Google Analytics has introduced the linker plugin. When you invoke the plugin, it returns a URL query parameter which includes the Client ID as well as a signature which is valid for 2 minutes. So, if you visit a different domain URL with the query parameter within the two minute window, cross-domain traffic could be setup between the two domains.
The two minute window exists to prevent linker parameters from persisting in shared links and browser history entries. Otherwise every time someone would follow a link with the linker parameter in place, they would be considered the original user who created the link. This would lead into a horrible mess, as it would be almost impossible to distinguish users from each other.
A typical way of loading the linker plugin is by using the autoLink feature of the plugin. When you use autoLink, you provide it with domain names that you want to automatically decorate with the linker parameters. Then when the user clicks a link or invokes a form redirection that has the given domain name as its target, autoLink automatically decorates the URL with the linker parameters.
In Google Tag Manager, you’d edit the Auto Link Domains field:
You’ll know its working when you see the _ga=1.234567.234567.234567 query parameter in the URL.
If you don’t see the parameter in the URL, it means that for some reason the autoLink plugin failed. Instead, you’ll need to manually decorate the URLs. This is particularly the case when working with iframes, as the iframe must be loaded with the linker parameters in its
src attribute, if you want cross-domain traffic to work between the parent page and the framed document.
To manually decorate the URLs, you or your web developer needs to write a piece of code which takes the linker parameter and appends it to the URL of the link or the iframe just before the document is loaded.
So, remember that for a basic cross-domain setup to work, the URL of the target page, whether opened by a link, redirected by a form, or loaded in an iframe, needs to have the linker parameter _ga=1.234567.234567.234567 in the URL.
Now you’ve got the URL query parameters in place, the Referral Exclusion List has all the necessary source domains, and you’re collecting data from both the source and target domain to the same Google Analytics Property.
Just one thing missing.
For the trackers in the target domain to respect the _ga=1.234567.234567.234567 linker parameter in the URL, you need to tell the trackers to allow the linker parameter to reset the Client ID on the target domain.
You do this by configuring the allowLinker field in the tracker object. In GTM, you’d simply add a new field:
This setting tells the tracker to use the Client ID embedded in the linker parameter rather than the one created by the tracker on the target domain.
You can verify that it’s working by opening the Network Tab in your web browser’s developer tools, and loading a page both on the source domain as well as on the target domain after following a cross-domain link, for example. All requests to /collect should have the parameter &cid use the same value. This tells you that the Client ID is the same across the domains.
There are many ways in which cross-domain tracking can malfunction, but there are actually only four moving parts to it:
- All domains need to collect data to the same Google Analytics Property
- All source domains need to be listed in the Referral Exclusion List of the Google Analytics Property
- The target domain URLs opened via the source domain need to be decorated with linker parameters
- The target domain Google Analytics trackers need to have the allowLinker field configured
Once all four of these pass inspection, cross-domain tracking should work without a hitch.