The following is the tale of some investigative work I did for a company which approached me to help them with their Google Analytics tracking for their online store. This company, like so many others, sells items on the Internet and wants to be able to properly attribute their sales to the correct channel using Google Analytics. Not surprisingly, in addition to having subdomains they were using a third party shopping cart and needed to have cross domain tracking configured. Pretty simple. Or so I thought…
As it turns out, the third party shopping cart they were using is called Shopify. As far as being an intuitive user interface that makes it easy for non-technical users to set up their store, I certainly see a lot of positives with Shopify. Unfortunately, Shopify also tried to make setting up Google Analytics “dumb proof.” In the end, trying to figure out why I couldn’t properly set up a simple, working basic GA tag led me to be “dumbfounded.” Shopify has a very simple interface where one simply needs to copy and paste their Google Analytics tracking code in order to get started.
However, as soon as you save the file, Shopify takes the Google Analytics code and rewrites it to match their own settings. In particular, they are choosing to _setDomainName to “none”, adding _setAllowLinker (which would indeed be required for cross domain tracking) and switched to dc.js. (I am not sure if the folks at Shopify paid attention or not, but to use the DoubleClick cookie, users are supposed to update their Privacy Policies accordingly. I didn’t see any sort of notification to do so on their site. Oops.)
Of particular interest to me is that Shopify is using setDomainName = none. As my friend Caleb Whitmore of Analytics Pros has told me on more than one occasion, “setDomainName(none) is the devil.” That is because in addition to removing the domain hash (which was deprecated as a requirement for cross domain tracking in August of 2011), this method writes the Google Analytics cookies to the EXPLICIT domain. In other words, if the site is www.example.com, then the GA cookies are written to WWW. If a site needs to do tracking across a subdomain, this is simply not possible using _setDomainName(none). When I first started providing code for Imogene and Willie (which has their main site template and the Shopify store on a “shop” subdomain), I began by providing them proper code that would handle both subdomain tracking (by setting GA’s cookie scope to the root domain), and cross domain tracking (by providing linker functions to bind to the action of form posts). I started my purchase process from their homepage (on WWW), and everything looked good.
But as I noted above, we were not able to update the setDomainName method on the Shopify store (shop.imogeneandwillie.com). As a result, we are forced to add linker functions that are normally reserved for true cross domain situations, in order to share the cookies across subdomains.
Now to the issue of cross domain tracking. Normally, one needs to use _link or _linkByPost to append cookie values to links and form posts respectively, or use _getLinkerUrl (the preferred method imho) to add the values directly to hrefs or form actions. Noticing that the site did not use any of these methods, my team provided script that would look for the particular form in the Shopping Cart and pass on cookie values so that they would make it to the Checkout.
The next page in the checkout funnel did indeed indicate that our code did have the proper cookie values passed to it.
But a very surprising thing happened when I navigated to the next page in the checkout process. My cookies were reset; i.e. the visit became a new Direct visit. Same domain (checkout.shopify.com). Same GA code (including the setDomainName nonsense). I was totally stumped and give major props to my man David Vallejo for finding this.
As it turns out, Shopify caches the GA cookies as they exist on their store and then writes them server-side within the checkout. Since, on the client side, in both the store and checkout they forcibly turn off domain hashing, as a user proceeds through the checkout their cookies are reset (wiped-out) if there is a discrepancy between the cookie value with domain hashing and the cookie value without it.
Ultimately, it seems to me that some of the developers at Shopify simply did not understand how GA’s cookies are supposed to work. It would have been a much cleaner solution if they would simply enable client-side cross domain tracking and not mess with the cookie scope (setDomainName) at all. Certainly, they should be more transparent about what they are doing in their documentation. I feel it is quite a lot of chutzpah on the part of Shopify to assume that they know what is best with regards to GA, and completely hijack the stores ability to configure GA in the correct way. To be fair, had they gotten it right I’d feel differently. As a personal note to developers out there, if you’re doing any sort of integration with Google Analytics, please work with a professional. From a developer standpoint, Google Analytics is really not that hard at all. However, “small” mistakes can have “huge” business ramifications. Don’t mess with this stuff unless you truly know what you’re doing.
Until next time,
Yehoshua
Aaron@Shopify says
Hi Yehoshua. Thanks for writing this article and your insights on this. I work at Shopify, and we will be re-evaluating our Google Analytics integration. I will comment on this article if there are any updates.
Yehoshua Coren says
Hi Aaron,
Glad to hear that Shopify is re-evaluating the GA integration. I know that I was approached about this issue by someone who had been in touch with Shopify technical support a number of times, but to no avail (which makes sense as the regular support team are experts with Shopify and not GA). Since Google Analytics is so mission critical for so many of your customers, I’m glad to hear that your team will be taking a look at this again and hopefully cleaning things up.
Yehoshua
Ollie B says
Yehoshua, were you able to get the Analytics set up for Imogene and Willie or were you stonewalled by the Shopify set up?
Yehoshua Coren says
We hacked together a working solution using less that ideal GA settings.
Les Faber says
@Yeshoa Coren: Did you read this today?: http://analytics.blogspot.ca/2014/11/brian-gavin-diamonds-sees-60-increase.html
Yehoshua Coren says
Yes, I did notice this announcement.
Les Faber says
@ Yehoshua: Any thoughts on it as related to your (most excellent) post? Didn’t really see anything that spoke to enabling GTM on Shopify sites.
Alicia Peyrano says
Hi Yeshohua,
What solution would you recommend for a Shopify store owner? What kind of developer would you recommend to get something clean and accurate set up. Our analytics are pretty useless at present. Are you free to take on a job? Thank you,
Alicia
Philip Pettifer says
The year is 2016 and we recently switched from Woocommerce to Shopify and have suffered ever since. We have no idea which channels are performing and which aren’t. It seems that if Shopify aren’t going to resolve such a monumental issue with their software, that we should simply revert back to Woocommerce. We are ALL blind without accurate analytics data.
Cannot believe a shopping based CMS would leave customers in such a disabled position!
Aivar says
Hi Aaron. Any news on this?
João Correia says
With Enhanced Ecommerce now public it is vital you provide more flexibility to track. Any updates on Shopify GA integration?
Aaron@Shopify says
Hi João. We’re working on updates to support the latest Universal features such as Enhanced Ecommerce. Please get in touch with me if you’d like to trial these in beta. Thank you.
[email protected]
Scott Monaghan says
Hi Yehosuha,
Thanks so much for the informative article. Were you ever able to get a solution where tracking worked through to the checkout pages?
We have a client having the same overall issue.
Client has their main site: http://www.clientsite.com
and their store: store.clientsite.com
Initially we had tracking working pretty good between the store and the mainsite by disabling google analytics on shopify and maually entering the code into the theme and using the following code to both sites:
_gaq.push([‘_setDomainName’, ‘.clientsite.com’]);
The problem we now realize, is that by turning of Shopify GA, we’ve lost all analyitics through the checkout process. We made a suggestion to the client to add an event to the click of “check out” as the final goal, but we know that’s not an ideal solution.
One hacky option we thought of trying was reactivating the shopify default GA code and adding the following GA code to the client’s main site:
_gaq.push([‘_setDomainName’, ‘store.clientsite.com’]);
In theory, now both sites should be tracked as “store.clientsite.com”. Any thoughts on this solution?
How did you end up finally solving the problem for Imogene and Willie?
Scott Monaghan says
I just checked out the code on Imogene and Willie.
Can you walk through this code and explain how your final hack worked?
Here is the code from their main site (also in first screenshot attached):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'XXXXXXXXXXXXX']);
_gaq.push(['_setDomainName', document.location.hostname.replace(/.*?([^.]+.com)/,'$1')]);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker',true]);
_gaq.push(['_addIgnoredRef', 'shopify.com']);
_gaq.push(['_addIgnoredRef', 'imogeneandwillie.com']);
_gaq.push(['_trackPageview']);
//apply linker function to all links to shop.imogeneandwillie.com
_gaq.push(function() {
var tracker = _gat._getTrackerByName();
_addEventListener(document,'mousedown',function(e) {
if (e.target.nodeName != 'A') {
return;
}
var link = e.target;
if (link.href.match(/shop.imogeneandwillie.com/)) {
link.href = tracker._getLinkerUrl(link.href);
}
});
});
Here is the code from the shopify site (also in second screenshot attached):
//Thanks to Eduardo Cereto for his cross-browser event listener and DOM ready function from the GAS library
function _addEventListener(e, t, n, r) { var i = function (t) { if (!t || !t.target) { t = window.event; t.target = t.srcElement } return n.call(e, t) }; if (e.addEventListener) { e.addEventListener(t, i, !!r); return true } else if (e.attachEvent) { return e.attachEvent("on" + t, i) } else { t = "on" + t; if (typeof e[t] === "function") { i = function (e, t) { return function () { e.apply(this, arguments); t.apply(this, arguments) } } (e[t], i) } e[t] = i; return true } }
function _DOMReady(e) { function n() { if (n.done) return; n.done = true; e.apply(t, arguments) } var t = this; if (/^(interactive|complete)/.test(document.readyState)) { return n() } _addEventListener(document, "DOMContentLoaded", n, false); _addEventListener(window, "load", n, false) }
_gaq.push(['_addIgnoredRef', 'shopify.com']);
_gaq.push(['_addIgnoredRef', 'imogeneandwillie.com']);
_gaq.push(function () {
var tracker = _gat._getTrackerByName();
_DOMReady(function () {
//update cart URL with linker
var cartform = document.getElementById('cartform');
if (cartform) {
cartform.action = tracker._getLinkerUrl(cartform.action);
}
//links to other domains also get linker function applied
var links = document.getElementsByTagName('A');
for (var i = 0; i < links.length; i++) {
var link = links[i];
if ((link.href.match(/checkout.shopify.com/) && document.location.hostname == 'checkout.shopify.com') ||
(link.href.match(/www.imogeneandwillie.com/) && document.location.hostname == 'shop.imogeneandwillie.com')) {
link.href = tracker._getLinkerUrl(link.href);
}
}
});
});
Any help would be much appreciated!
Aaron@Shopify says
Hi everyone,
Here is an update on this. We have updated our Universal Analytics code to ensure proper cross-domain tracking (between the Shopify storefront and checkout.shopify.com) is done, and are also recommending that all stores use Universal Analytics as that is the current version with latest support on Shopify.
Our documentation has been updated to give setup instructions for Universal Analytics (including remarketing): http://docs.shopify.com/manual/settings/general/google-analytics
Here is what Universal Analytics code now looks like on any Shopify site with Universal Analytics enabled: https://gist.github.com/aSadhankar/6d8e7272379d033ecaa3
If you have any feedback or questions, please let me know. Thanks!
João Correia says
Hi Aaron,
Having the copy/paste code for GA is nice for most users but you should enable something more flexible to power users. Im configuring Shopify to two Analytics, Snowplow and GA Universal with Enhanced Ecommerce. Im hitting serious roadblocks to track the checkout process just because I cant use Google Tag Manager without configuring GA on Shopify, which messes all tracking.
Would you consider a support for tag management systems across your checkout process? It would help a lot.
Aaron@Shopify says
Hi João. Although it is only a minority of stores that would require more advanced script management, this is something we are looking into. We are evaluating support for Google Tag Manager as well. Please feel free to get in touch with me as I would like to hear what you’re trying to implement and the roadblocks you are hitting. Thank you.
[email protected]
Les Faber says
Just wondering about the integration of Google Tag Manager with Shopify stores?
Elliot Walker says
I too would like to know the progress of ability to integrate Google Tag Manager in Shopify. Anyone know how to do this?
Les Faber says
As of this writing, I do not think it is possible (out of the box). There may be a way to hack one of their store templates. Not sure. Hoping that @disqus_4eVCVv2zk5:disqus will chime in soon.
Joshua Heien says
Has this been resolved where you don’t need the code listed from github? Or can I use the standard universal analytics from google?
shopifydoctor says
The thing I love about this article, which you mentioned in the comment above, is that the real goal here is to really think through all the options available to you in Shopify Developers. Thanks for sharing in article.
Ruby shaikh says
Hi , I found your article to be very informative and a great guide to those who are new to
Seriously though, really awesome and helpful post.
I’ve been considering starting in e-commerce and
this is exactly the type of info I’m looking for.
Shopify Ottawa
Modish Living says
Hi all, is anyone able to help with getting GA working fully with Shopify? We have exhausted the help team at both Shopify and Google, however our problem is we are running adwords campaigns blindly. I’ve been told its to do with the cross domain, however no matter what code i get told to change, GA isn’t attributing sales to adwords campaigns.
Joshua Uebergang says
Have you linked your AdWords with Analytics? It is one of the easy things to do.
Also encourage you to go through this complete guide I wrote about how to get your Google Analytics perfect for Shopify: https://www.digitaldarts.com.au/google-analytics-and-shopify-for-splendid-data
Marcio says
Joshua Uebergang
Although it is a pretty good post, I don’t believe it address the problem, Joshua.
I’ve been experiencing something similar. 95% of my sales come from facebook (I know because that’s the only place I advertise at, and also because I see facebook number and the I was not selling much before that campaign). However analytics is showing 99% of my sales as “direct”. I can also see on analytics that 90% of my visits come from facebook.
Would you know how to solve that?
Best
Marcio
Joshua Uebergang says
Read section 11 of the guide about UTM campaigns. That solves direct issues for analytics in Shopify.