Multisite cookie handling

The problem

Recently I had a requirement for the following scenario, which at first seemed straight forward, but ended up needing a little more work than expected!

On an existing mulitsite XP SXA/JSS install I needed:

  • 2 sites to share an analytics cookie for cross site tracking of contacts
    • EG. Sites with the following hostnames abc.site.com and def.site.com should share the same SC_ANALYTICS_GLOBAL_COOKIE cookie by setting the cookie domain to .site.com .
  • Other sites to just use their default hostname for the analytics cookie.
    • EG. my.example.com

In simpler scenarios there is the option to just change the Analytics.CookieDomain setting in config to the appropriate domain, however, this applies instance-wide and there is no OOTB provision to do this on a site by site basis. Using this method I couldn’t ensure cookies would be set on the correct domain for .site.com and my.example.com

The solution

The solution was to devise a strategy to allow each site to explicitly set the analytics cookie domain, but fallback to default behaviour where nothing is set. To do this we used the SXA Site’s other properties field, but in a non-SXA world, could just as easily be done via the site config with some additional parameters. We can then patch into the StartAnalytics pipeline to override the analytics cookie domain when the cookie is getting set.

Step 1

Add a cookieDomain key value pair to the SXA Site Other Properties field in the site settings of the sites you wish to augment. In the example case above, I added the following property to the site settings for abc.site.com and def.site.com. No changes were needed to the my.example.com site as it can just use default behaviour.

Path to Site settings item:
sitecore/content/<tenant>/<site>/Settings/Site Grouping/<site>

Add a Key/Value pair of:
cookieDomain
.site.com

Step 2

Patch in a processor to the StartAnalytics Pipeline. This will do a few things:

  • Check if there is a cookieDomain property set in the Site context.
  • Check if an analytics cookie has been attempted to be set that HTTP request/response
  • If all is well, change the domain of the cookie that has already been set in the HTTP response object to the value of “cookieDomain” site property,

Following this method will ensure default behaviour where the site property is not explicitly set.

Create the processor:

using Sitecore.Analytics;
using Sitecore.Analytics.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Pipelines;
using System.Linq;
using System.Web;

namespace GWDT.Foundation.Analytics.CookieDomain
{
    public class SetSiteAnalyticsCookieDomain
    {
        public virtual void Process(PipelineArgs args)
        {            
            Assert.ArgumentNotNull((object)args, nameof(args));
            if (!Tracker.IsActive) { 
                return; 
            }
            
            //Is there a Site level cookie domain set? 
            var siteCookieDomain = Sitecore.Context.Site.Properties.Get("cookieDomain");
            if (string.IsNullOrEmpty(siteCookieDomain) ||
                siteCookieDomain == AnalyticsSettings.CookieDomain
                )
            {                
                return;
            }

            //Has a cookie been set for this response?
            string cookieName = "SC_ANALYTICS_GLOBAL_COOKIE";
            HttpContext current = HttpContext.Current;
            if (current == null || !current.Response.Cookies.AllKeys.Contains(cookieName))
            {                
                return;
            }

            var cookie = current.Response.Cookies[cookieName];
            if (cookie !=null && cookie.Domain != siteCookieDomain)
            {                
                cookie.Domain = siteCookieDomain;
            }
        }
    }
}

Patch it into the StartAnalytics pipeline.

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
	<sitecore>
		<pipelines>			
			<startAnalytics>
				<processor type="GWDT.Foundation.Analytics.CookieDomain.SetSiteAnalyticsCookieDomain, GWDT.Foundation.Analytics" resolve="true" 
                   patch:after="*[@type='Sitecore.Analytics.Pipelines.StartAnalytics.StartTracking, Sitecore.Analytics']"/>
			</startAnalytics>			
		</pipelines>
	</sitecore>
</configuration>

Step 3

Test and sip Margaritas by the pool. 🍹🏊‍♂️

Leave a comment