We’ve migrated our documentation to a new site, which means some URLs have changed.
Audience

Cross-site user tracking in Safari

NB!

We now have automatic cross-site tracking in place for Safari, so this script is no longer needed.

NB!

Background and motivation

Apple has introduced domain isolation for both Local Storage and file cache in Safari 7 and up. This effectively stops cross-site tracking of users using the latest Safari browsers on iPhone, iPad and Macs. New users and users that clear their cookies are no longer tracked cross site.

Resolution

The problem of domain isolation can be resolved by redirecting all new users into the cxense.com domain, generating an unique ID there and setting this ID as a first party cookie. This method gives 100% coverage of users in all browsers.

Method break down

  1. A new type of tag is added to the <head> part of all pages

  2. This tag checks if the browser is Safari and that we have not already done the redirect (redirect status stored in a cookie)

  3. If we have not done the redirect and the browser is Safari, the real referrer is temporarily stored in sessionStorage and the browsers is redirected to a webpage on the cxense.com domain.

  4. The page on the cxense.com domain tries to read a user id cookie. If it is set, the client is redirected back immediately. If it is not set, create a random id. This is set as a fist party cookie on the cxense.com domain. Finally redirect back to the your page, with a flag indicating that the cookie have been etablished.

  5. Your page loads again, and this time the URL includes the redirect to token. The script also reads back the real referrer from sessionStorage and stores its value in cX.documentReferrer.

  6. In any other case, the script stores the current referrer document.referrer in cX.documentReferrer, so that in all cases, the real referrer can be read from cX.documentReferrer.

  7. At some point later, cx.js loads and a sendPageViewEvent() call is made

  8. 3rd party cookies will now work because they are set in a 1st party context and read in a 3rd party context. 

<!-- Cx Safari cross-site tag begin
        Note 1: This tag must be placed just after the opening <head> tag for the best user experience and to give precise analytics reports
        Note 2: When using this tag, the referrer must be read with cX.documentReferrer (and not document.referrer)
        Note 3: the 'tld =' line should be replaced with 'tld="your-top-level-domain"' to reduce the number of redirects required.
-->
<script type="text/javascript">
(function(w, u, l, d, h, v, r, cdn, tld,date) {
    w.cX = w.cX || {};
    if (w.top === w.self && u.match(/Safari/) && !u.match(/Chrome|bot|link/) && d.cookie.indexOf(v) < 0) {
        if (l.href.indexOf(r) < 0) {
            cdn = l.protocol === 'https:' ? 'https://scdn.cxense.com/' : 'http://cdn.cxense.com/';
            w.sessionStorage.setItem('_cX_originalReferrer', d.referrer);
            l.replace(cdn + 'rid.html?location=' + encodeURIComponent(l.href));
        } else {
            // TODO: replace this value with the actual top domain. This will lead to fewer redirects
            tld = w.location.hostname;
            date = new Date();
            date.setFullYear(date.getFullYear() + 1);
            d.cookie = v + "=1;" + ";path=/;domain="+ tld +";expires=" + date.toUTCString();
            if (h && typeof h.replaceState === 'function') {
                h.replaceState({}, '', l.href.replace(r, ''));
            }
            cX.documentReferrer = w.sessionStorage.getItem('_cX_originalReferrer');
        }
    }
    if (typeof cX.documentReferrer === 'undefined') {
        cX.documentReferrer = document.referrer;
    }
})(window, navigator.userAgent, window.location, document, window.history, 'cX_gckp_redirect', '#gckp_redirect=true');
</script>
<!-- Cx Safari cross-site tag end -->

 

Required changes for other scripts on the page

To get the correct real referrer reported to other scripts on the page, they must be changed to read the cX.documentReferrer instead of document.referrer. This is done automatically by cx.js.

Example on how to update Google Analytics. Add this one line:

<script type="text/javascript">
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  
    ga('create', 'UA-123123123123-1', 'mysite.com');
    ga('set', 'referrer', cX.documentReferrer); // <-- Needed to get the correct real referrer in all cases
    ga('send', 'pageview');
</script>

 

Minified version of the script

This is the same script as on the top of this page, but it has been minified. In some situations a smaller script is preferred. The same requirements apply;

  • This tag must be placed just after the opening <head> tag for the best user experience and to give precise analytics reports

  • When using this tag, the referrer must be read with cX.documentReferrer (and not document.referrer)

  • The 'tld =' line should be replaced with 'tld="your-top-level-domain"', e.g. 'tld="http://mydomain.com "' to reduce the number of redirects required.

<!-- Cx Safari cross-site tag begin -->
<script type="text/javascript">
    var tld = location.hostname; // TODO: Set top level domain here
    !function(e,r,t,o,c,n,i,a,d){e.cX=e.cX||{},e.top===e.self&&r.match(/Safari/)&&!r.match(/Chrome|bot|link/)&&o.cookie.indexOf(n)<0&&(t.href.indexOf(i)<0?(a="https:"===t.protocol?"https://scdn.cxense.com/":"http://cdn.cxense.com/",e.sessionStorage.setItem("_cX_originalReferrer",o.referrer),t.replace(a+"rid.html?location="+encodeURIComponent(t.href))):(d=new Date,d.setFullYear(d.getFullYear()+1),o.cookie=n+"=1;;path=/;domain="+tld+";expires="+d.toUTCString(),c&&"function"==typeof c.replaceState&&c.replaceState({},"",t.href.replace(i,"")),cX.documentReferrer=e.sessionStorage.getItem("_cX_originalReferrer"))),"undefined"==typeof cX.documentReferrer&&(cX.documentReferrer=document.referrer)}(window,navigator.userAgent,window.location,document,window.history,"cX_gckp_redirect","#gckp_redirect=true");
</script>
<!-- Cx Safari cross-site tag end -->

 

 

Last updated: