This blog examines a way in which you can effectively track a user across multiple sites with different domains. It demonstrates how visitor data collected across different top-level domains can be merged together. Merged visitor data provides a much clearer picture of a users movements (experience profile timeline) when a brand consists of many different websites.

You can view Part 1, Part 3 and  Part 4 via the respective links.


Note:  Tracking across sub-domains is a much easier task in Sitecore and is solved using the setting “Analytics.CookieDomain”. The problem this blog is solving is about top level domains not being able to identify and merge visits. This is due to the fact that top-level domains cannot access each others analytics cookie (for very valid security reasons). The problem is summarised well here.


Why is this necessary?

To start off with let’s define the current problem that required this solution.

Problem Definition:

Given that two websites are hosted in Sitecore under unique top level domains. If a visitor goes to http://www.abc.com.au and then visits http://www.def.com.au the same visitor is not linked and the Experience Profile shows two different visitors.

Solution:

The solution Aceik came up with for this is best depicted with a simple diagram.

GlobalCookie

(download a bigger diagram)

The different technologies at play in the diagram include:

  1. Multiple Sitecore Sites
  2. Google Analytics or GTM
  3. IFrames – running javascript, using PostMessage, with domain security measures.
  4. Cookies – Top Level Domain

What is happening in Simple Terms?

Essentially a user visits any one of your Sitecore sites and we tell XDB how it can identify that user by using the assigned Google Client ID.

To do this we use a combination of IFrame message passing between a group of trusted sites and cookies that give us the ability to go back and get the original Client ID for reuse.

By reusing the same Google Client ID on all Sitecore sites we can produce a more complete user profile. One that will contain visit data from each website. The resulting timeline of events in the Experience Profile will now display a federated view across many domains.


A More Technical Explanation

This is a more detailed Technical explanation. Let’s break it down into the sequence of steps a user could trigger and the messages being passed around.

First visit to “def.com.au”:

  1. User navigates to “def.com.au”.
  2. Google analytics initializes on page load with a random Client ID (CID) assigned.
  3. Async JavaScript is used to inject an invisible IFrame into the page. The IFrame URL is pointed at “abc.com.au/cookie”.
  4. Once the IFrame has completed loading the URL JavaScript obtains the CID from Google and uses “PostMessage” to pass it through to the “Global CID Cookie”.
  5. The “Global CID Cookie” has no prior value set so is updated with the CID passed in.
  6. The cookie page responds using “PostMessage” and sends back the same CID passed in.
  7. JavaScript on the page “def.com.au” receives the message and stores the CID received in the “Domain CID Cookie”.
  8. JavaScript on the page triggers backend code that will identify the user against the CID and merge all visits for that user.

Later visit to “hij.com.au”

  1. User navigates to “hij.com.au”.
  2. Google analytics initialisers on page load with a random Client ID (CID) assigned.
  3. Async JavaScript is used to inject an invisible IFrame into the page. The IFrame URL is pointed at “abc.com.au/cookie”.
  4. Once the IFrame has completed loading the URL JavaScript obtains the CID from Google and uses “PostMessage” to pass it through to the “Global CID Cookie”.
  5. The “Global CID Cookie” has a prior value, so the CID passed in is not used or set.
  6. The cookie page responds using “PostMessage” and sends back the prior existing CID stored from the first visit to”def.com.au”.
  7. JavaScript on the page “hij.com.au” receives the message and stores the CID received in the “Domain CID Cookie”.
  8. JavaScript on the page triggers backend code that will identify the user against the CID.  The current visit data for  “hij.com.au” is merged with the previous visit data from “def.com.au”.
  9. JavasScript on the page updated the CID stored in Google Analytics so that no other actions use the newer CID generated by “hij.com.au”.
  10. When the page is refreshed the Google Analytics initialisation code checks the “Domain CID Cookie” and passes through the existing CID to google for continued use.

Last visit to “abc.com.au”

  1. Google analytics initialisers on page load, checks for the existence of the “Global CID Cookie” and passes through the existing CID to google for continued use.
  2. Javascript on the page notices that “Global CID Cookie” is set but the “Domain CID Cookie” is not.
  3. JavaScript on the page triggers backend code that will identify the visit against the CID.  The current visit data for  “abc.com.au” is merged with the previous visit data from “def.com.au” and “hij.com.au”.

Second-time visits are an easy win

Once each domain has completed a first pass of checking for a Global CID the code is smart enough that it doesn’t need to repeat all these steps again.

The first pass sets a local domain cookie and this is used for quick access on each subsequent page load. The first pass is also coded in an async way so that it will not have an impact on page load times.

We can also set it up so that the code initialising the google tracker is instantly provided with the multi-domain Client ID straight away.

https://www.useloom.com/share/0b8c9f0a2fbc41c0baa1ae4db5e9ae6b

This loom video shows exactly how we set up the global page view event with two variables. The final variable runs custom javascript that will read our cookie to grab the Client ID.

The javascript to paste into the GTM variable is:

function() {
var getGAPrior = function(name) { var value = "; " + document.cookie; var parts = value.split("; " + name + "="); if (parts.length == 2) return parts.pop().split(";").shift(); }
var localCookie = getGAPrior("LocalCidCookie"); if (typeof localCookie !== "undefined") { return localCookie; }
var globalCookie = getGAPrior("GlobalCidCookie"); if (typeof globalCookie !== "undefined") { return globalCookie; }
return null;
}

What about FXM ?

You could potentially solve this same problem using a customisation around FXM.  It may be possible for FXM to replace the need for IFrame communication.

In order to achieve this, you would need to write a customisation to the Beacon service that allowed a Google Client ID to be sent and received.

However, the main sticking point remains around the need to maintain a global storage area (Global Cookie) that is owned by the user.  Due to the browser limitations (noted by Sitecore) of passing cookies, I’m not entirely sure an FXM replacement will work.

Compare that with browser support for IFrame “PostMessage” and you can see why we travelled down one rabbit hole compared to another.

Reference: https://community.sitecore.net/developers/f/10/t/380


Conclusion

Every website visitor gets assigned a Google Analytics Client ID.  You can use this ID to identify a user in XDB very early on. For multi-site tracking, the Client ID supplied by Google comes in very handy.  By using some clever communication tactics between your sites you can merge all the users visit data into a single profile view. The resulting timeline of events in the Experience Profile should prove very useful to your marketing teams.

To continue reading, jump over to Part 3 where we cover off External Tracking via FXM and Google Client ID.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s