This article will guide you through how to use Tealium iQ Tag Management to track between two separate domains.
Table of Contents Placeholder
Why use a First Party Cookie Sync between domains?
You would want to use this method if you have a need to track certain key/value pairs from one domain to another. For example:
You have siteA.com which is your online documentation website. Your online documentation site receives a lot of traffic but has no forms to track query string parameters (utm_campaign, utm_source, utm_medium, cid, etc.) all the way to database/CRM level.
You also have siteB.com which does have forms with hidden form fields that can read query string parameters, like utm_campaign, but there is no easy way to transfer this tracking from siteA.com to siteB.com.
The Tealium First Party Cookie Sync solves for this issue by saving the query string parameters in an iframe cookie that can then be read and used by a Tealium iQ Profile and shared across both siteA.com and siteB.com.
First Party Cookie Sync allows tracking across multiple domains so you can understand your customer's complete journey.
Prerequisites
You must upload a simple iframe HTML file to each of the sites that you want to share data between.
You must create a new profile. Learn more about creating a new profile in Managing Profiles document.
Steps
1) Profile Creation
Create a brand new profile called "cookie-sync-frame" in your account. Read the Managing Profiles document to learn how to create a brand new profile.
Your Account > Profile list should now look like this:
2) The iframe HTML file
Create an HTML file named iframe.html and place this code inside it:
<html>
<head>
<title> iframe Page </title>
</head>
<body>
<script type = "text/javascript" >
var utag_data = {
}
</script>
<script type = "text/javascript" >
( function ( a , b , c , d ){
a = '//tags.tiqcdn.com/utag/ACCOUNT/cookie-sync-frame/prod/uta g.js' ;
b = document ; c = 'script' ; d = b . createElement ( c ); d . src = a ; d . type = 'text/java' + c ; d . async = true ;
a = b . getElementsByTagName ( c )[ 0 ]; a . parentNode . insert Before ( d , a );
})();
</script>
</body>
</html>
Or download the iframe.html attached to this document.
This HTML file must be a stand-alone file. The above code cannot be added to any other file. Also remember to replace ACCOUNT in line 12 with your actual account name.
Upload this stand-alone iframe.html file to both siteA.com and siteB.com.
Remember the URLs where these iframe.html files lives. You will need this information for Step 4.
3) Setting up your Data Layer Variables
Variables that Need to be Created for ALL Profiles
For the purposes of training we'll continue using the Google Analytics variables utm_campaign, utm_source, utm_medium, utm_term, and utm_content as examples. In all 3 profiles, siteA.com, siteB.com and cookie-sync-frame, you will need to create variables in your data layer for utm_campaign, utm_source, utm_medium, cid, etc.
Add the utm Querystring Parameter variables to your data layer. Learn how in this adding data layer variables tutuorial.
Also add the utm variables as First-Party Cookie variables to your data layer. Again, learn how in this data layer lesson.
As a best practice it is recommended that you prepend your First-Party Cookie variables with "utag_main_".
Once complete your data layer should look something like this:
Variable that Needs to be Created ONLY in cookie-sync-frame
In the cookie-sync-frame profile you will need to create one more First-Party Cookie variable called "utag_main_iframes_loaded". We'll utilize this variable later in this tutorial to store the 'master' cookie that will be shared between siteA.com and siteB.com. Your data layer should look something like this when complete.
4) Site Profiles Setup
Setup for siteA.com, siteB.com, etc.
For siteA.com, siteB.com etc. use a JavaScript Code Extension within Tealium iQ and add the following code:
You'll need to update the utag.ut.domains object to specify the top level domain name (applying siteA.com, not www.siteA.com) and the path to the html file that was uploaded.
Utilizing utag.ut.iframeQueryString.push inside the utag.ut.processIFrames function (defined in the JavaScript code below), you can add whatever data points you want to capture from the current domain to sync to the other domains. The code to pull out data points will run on document complete, so you will know that everything has already been set by the tags. For example, the sample code is pulling the Google Analytics and cid querysting parameters from the URL.
//Make sure we have the ut object in utag
utag . ut = utag . ut || {};
//Specify all top level domains and the specific location for the iframe
utag . ut . domains = {
"siteA.com" : "//siteA.com/iframe.html" ,
"siteB.com" : "//siteB.com/iframe.html" ,
"siteC.com" : "//siteC.com/iframe.html"
}
utag . ut . processIFrames = function (){
//Build the querystring params
utag . ut . iframeQueryString = [];
//Capture the UTM Parameters
utag.ut.iframeQueryString.push( "utm_campaign=" + (utag.data[ "cp.utag_main_utm_campaign" ] || ''));
utag.ut.iframeQueryString.push( "utm_source=" + (utag.data[ "cp.utag_main_utm_source" ] || ''));
utag.ut.iframeQueryString.push( "utm_medium=" + (utag.data[ "cp.utag_main_utm_medium" ] || ''));
utag.ut.iframeQueryString.push( "utm_term=" + (utag.data[ "cp.utag_main_utm_term" ] || ''));
utag.ut.iframeQueryString.push( "utm_content=" + (utag.data[ "cp.utag_main_utm_content" ] || ''));
utag.ut.iframeQueryString.push( "cid=" + (utag.data[ "cp.utag_main_cid" ] || ''));
//Need to know how many iframes we create
utag . ut . iframeCreateCount = 0 ;
//Need to know how many iframes loaded
utag . ut . iframeProcessedCount = 0 ;
//Go through each of the keys in the domains object
for ( var d in utag . ut . domains ){
//Ignore the domain if it's the same as the current site
if ( utag . ut . domains . hasOwnProperty ( d ) && d !== utag . data [ "ut.domain" ]){
//Increment the count of iframes being created
utag . ut . iframeCreateCount ++;
//Create the iframe
utag . ut . loader ({ "type" : "iframe" , "src" : utag . ut . domains [ d ] + "?" + utag . ut . iframeQueryString . join ( "&" ), "cb" : utag . ut . processedIFrame , "loc" : "body" });
}
}
}
utag . ut . processedIFrame = function (){
//Increment how many iframes loaded
utag . ut . iframeProcessedCount ++;
//Check to see if we have loaded all iframes needed
if ( utag . ut . iframeCreateCount === utag . ut . iframeProcessedCount ){
//Set a cookie so that we don't need to do this again
utag . loader . SC ( 'utag_main' , { "iframes_loaded" : "true" });
}
}
//Create a window level event listener function
utag . ut . addWindowEvent = function ( evnt , funct ) {
try {
if ( window . attachEvent ) {
return window . attachEvent ( 'on' + evnt , funct );
}
return window . addEventListener ( evnt , funct , false );
} catch ( e ){
try {
console . log ( 'addWindowEvent failed: ' + e );
} catch ( e ){}
}
};
//Only add an event listener if the iframe sync hasn't happened before
if (! utag . data [ "cp.utag_main_iframes_loaded" ]){
//Once doc complete, create the iframes
utag . ut . addWindowEvent ( "load" , utag . ut . processIFram es );
}
Scope the extension to "DOM Ready" and name the extension "First Party Cookie Sync Extension".
You do not need to create this "First Party Cookie Sync Extension" within the cookie-sync-frame profile.
5) Persist Data Extension
For All Profiles
You will now need to use the Persist Data Value Extension for all 6 of your Querystring Parameter variables (utm_campaign, utm_source, utm_medium, utm_term, utm_content, and cid). Learn more about the Persist Data Value Extension. We recommend that you scope the extensions to "All Tags" and execute the extensions after load rules.
6) Setting up utag_main_iframes_loaded in the cookie-sync-frame profile
After all of the data points have been established, we need to set the "utag_main_iframes_loaded" cookie so that when the user visits any other domain configured, the iframe sync does not occur again.
In the "cookie-sync-frame" profile add another Persist Data Extension .
Name it "Set utag_main_iframes_loaded"
Scope it to "All Tags" and makes sure that it executes "After Load Rules"
What you set Persist, Duration, Update, and Condition to depends on your organization's needs.
Store in Cookie should use the "utag_main_iframes_loaded" First-Party Cookie we created earlier.
It is best practice to have this extension load last in the Extensions list.
FAQ
How do I test that my implementation worked?
On siteA.com create a URL that you can test with. Continuing with the theme of Google Analytics querystring parameters, use a URL like the one below: https://siteA.com/?utm_campaign=testA&utm_source=testA&utm_medium_testA&utm_term=testA&utm_content=testA&cid=testA.
In Chrome Developer Tools, open the Application tab, under Storage / Cookies, click https://siteA.com then over the results of utag_main cookie in the right-most section. The utm variables and their values should be captured in that cookie.
Go to https://siteB.com.
Again under Storage / Cookies, click https://siteB.com and hover over the utag_main cookie. You should see the same utm parameters and their values in siteB.com's utag_main cookie.
Alternative Troubleshooting Techniques
Within the Chrome Developer Tools Network tab, verify that the cookie-sync-frame appears in the Network window by opening up one of your profile sites, in Incognito Mode, and looking for the cookie-sync-frame.html file.
Can I use variables other than Google Analytics parameters?
Of course! The utm parameters are used as an example. You can use any key/value pairs desired just as long as you adjust the code in Step 4 and any variables in the data layer.
... View more