Conversion tracking configuration for Google Analytics

Highlighted
Excursionist
44 0 10

Hi Mike.  Thanks very much for the input.  I have indeed used the Shopify...General...Settings method in the past.  I went away from it because I am actually using two GA tracking codes simultaneously - one for GA "Classic" and one for GA "Universal Analytics" - and the Shopify  Settings thing cannot handle that.  That's why I went to doing it "by hand".  Based on what you're saying I may just forget about GA Universal Analytics, just stick with GA Classic, and go back to the Settings method... You are the first person who told me that Shopify takes care of the cross-domain stuff when you use the Settings method.  I asked Shopify Support what I might "lose" by doing it the other way, and they never said anything about that...

What a pain.... I wish Shopify would more fully support Google Analytics (e.g. multiple GA tags, etc)... I also wish they would better document what they are doing with their "Google Analytics" black magic...

Here is my checkout code in all it's glory.  As far as I can tell either the GA ecommerce tracking is not working OR it's working but I don't have GA set up to see cross-domain stuff.

<!-- google conversion tracking code (adwords) -->
<script type="text/javascript">
	/* <![CDATA[ */
	var google_conversion_id = XXXXXXXXX;
	var google_conversion_language = "en";
	var google_conversion_format = "3";
	var google_conversion_color = "ffffff";
	var google_conversion_label = "xxxxxxxxxxxxxxxx";
	if ({{ total_price }}) { var google_conversion_value = {{ total_price | money_without_currency }}; }
	var google_remarketing_only = false;
	/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js"></script>;
<noscript>
	<div style="display:inline;">
		<img height="1" width="1" style="border-style:none;" alt="" src="//www.googleadservices.com/pagead/conversion/XXXXXXXXX/?value={{ total_price | money_without_currency }}&amp;label=xxxxxxxxxxxx&amp;guid=ON&amp;script=0"/>
	</div>
</noscript>

<!-- google dynamic remarketing tag (adwords) -->
<script type="text/javascript">
	var google_tag_params = {
	{% if line_items.size > 1 %}
		ecomm_prodid: [{% for line_item in line_items %}'{{ line_item.variant.id }}'{% if forloop.last != true %},{% endif %}{% endfor %}],
	{% elsif line_items.size == 1 %}
		ecomm_prodid: {% for line_item in line_items %}'{{ line_item.variant.id }}'{% endfor %},
	{% else %}
		ecomm_prodid: '',
	{% endif %}
		ecomm_pagetype: 'purchase',
		ecomm_totalvalue: '{{ total_price | money_without_currency }}'
	};
</script>
<script type="text/javascript">
	/* <![CDATA[ */
	var google_conversion_id = XXXXXXXXX;
	var google_custom_params = window.google_tag_params;
	var google_remarketing_only = true;
	/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js"></script>;
<noscript>
	<div style="display:inline;">
		<img height="1" width="1" style="border-style:none;" alt="" src="//googleads.g.doubleclick.net/pagead/viewthroughconversion/XXXXXXXXX/?value=0&amp;guid=ON&amp;script=0"/>
	</div>
</noscript>

<!--
google analytics "classic" tracking code 
feeds google analytics account UA-XXXXXXXX-2
-->
<script type="text/javascript">

	var _gaq = _gaq || [];
	// var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';;
	// _gaq.push(['_require', 'inpage_linkid', pluginUrl]);
	_gaq.push(['_setAccount', 'UA-XXXXXXXX-2']);
	_gaq.push(['_setDomainName', 'checkout.shopify.com']);
	_gaq.push(['_setAllowLinker', true]);
	_gaq.push(['_trackPageview']);
	_gaq.push(['_set', ‘currencyCode’, ‘USD’]);
  
	_gaq.push(['_addTrans',
		'{{ order_number }}',								// transaction ID - required
		'{{ shop_name }}',  								// affiliation or store name
		'{{ total_price | money_without_currency }}',		// total - required
		'{{ tax_price | money_without_currency }}',			// tax
		'{{ shipping_price | money_without_currency }}',	// shipping
		'{{ shipping_address.city }}',						// city
		'{{ shipping_address.province }}',					// state or province
		'{{ shipping_address.country }}'					// country
	]);

	{% for line_item in line_items %}
		_gaq.push(['_addItem',
			'{{ order_number }}',								// transaction ID - required
			'{{ line_item.sku }}',								// SKU/code - required
			'{{ line_item.title }}',							// product name
			'{{ line_item.id }}',				// category or variation
			'{{ line_item.price | money_without_currency }}',	// unit price - required
			'{{ line_item.quantity }}'							// quantity - required
		]);
	{% endfor %}

	_gaq.push(['_trackTrans']);		//submits transaction to the Analytics servers


  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://'; : 'http://';) + 'stats.g.doubleclick.net/dc.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
  
</script>

<!--
google analytics "universal analytics" tracking code 
feeds google analytics account UA-XXXXXXXX-1
-->
<script>

	(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-XXXXXXXX-1', 'occitanimports.com');
	ga('require', 'ecommerce', 'ecommerce.js');

	ga('ecommerce:addTransaction', {
		'id': '{{ order_number }}',										// Transaction ID. Required.
		'affiliation': '{{ shop_name }}',								// Affiliation or store name.
		'revenue': '{{ total_price | money_without_currency }}',		// Grand Total.
		'shipping': '{{ shipping_price | money_without_currency }}',	// Shipping.
		'tax': '{{ tax_price | money_without_currency }}',				// Tax.
		'currency': 'USD'												// local currency code.
	});  

	{% for line_item in line_items %}
		ga('ecommerce:addItem', {
			'id': '{{ order_number }}',									// Transaction ID. Required.
			'name': '{{ line_item.title }}',							// Product name. Required.
			'sku': '{{ line_item.sku }}',								// SKU/code.
			'category': '{{ line_item.id }}',			// Category or variation.
			'price': '{{ line_item.price  | money_without_currency }}',	// Unit price.
			'quantity': '{{ line_item.quantity }}',						// Quantity.
			'currency': 'USD'											// local currency code.
		});
	{% endfor %}
	
	ga('ecommerce:send');
	ga('send', 'pageview');

</script>

 

0 Likes
Highlighted
Shopify Partner
52 0 7

Hi again Lolo!

It sounds like you are not having a great time with GA & Shopify which is a massive shame. It is certainly tricky to get multiple trackers working however I did manage to help another shop owner who had a similar problem with the standard Universal Analytics implementation (i.e. via the settings section). Out of the box Shopify does not support Universal ecommerce tracking however there is currently a beta test programme that enables cookie data to be passed from your store front to the payment (checkout.shopify.com) for Universal Analytics. It works so might be worth looking at...

Mike

A Positive10 Peep
0 Likes
Highlighted
Shopify Partner
52 0 7

 

Hi all,

I thought I'd give some more background to how Shopify deals with GA tracking (at least the way I interpret it). Effectively there are 2 main ways you can implement analytics of any kind in Shopify - the traditional and most trouble free method is via the main settings in your myshopify.com admin/settings/general dashboard under the Google Analytics section. Its actually a very powerful section so keep this in mind for later... The second method is to include it as a snippet or add directly to your main theme.liquid templates. 

Adding snippets directly into your template files gives you some control over how scripts like GA are fired on your core shop front pages. Unfortunately the template files do not effect code within the checkout/payment processing section of the process. Typically all checkout functionality is handled on a checkout.shopify.com subdomain. Code can only be added to checkout.shopify.com pages via the /admin/settings/general analytics section (with the exception of the thank you/payment confirmation page). However remember that this analytics section does not allow liquid variables.

Google Analytics needs to pass data between subdomains and root domains and does so through the use of cookies. If cookies are not passed then data such as source of traffic and GA visit information will not pass and new visit information will be logged. Typically self referrals are often the result of incorrectly setting up how cookie data is passed between subdomains and between root domains. 

Shopify ordinarily passes cookie data between your store front domain and the checkout.shopify.com subdomain when users opt for the general settings approach in the Shopify Admin. Unfortunately when you use any other method (e.g. adding code to the template files) the cookie data is no longer passed. This includes when you only add analytics code to the /admin/settings/payments "Additional content & scripts" section. 

So in short you have to use the myshopify.com admin sections if you want to track from your domain to checkout.shopify.com.

However!!! This doesn't mean Shopify is inflexible - far from it! You can/should be able to do things like track multiple UA and cross subdomains bearing a lot of the stuff above in mind. The below demonstrates a combination of using both /admin/settings/general Google Analytics section and (/admin/settings/payments Additional content & scripts)

  • Firstly remember that only the confirmation page (/admin/settings/payments "Additional content & scripts") on checkout.shopify.com can include liquid variables. This is actually useful as you could create a javascript object to collect transaction data that is typically used for GA ecommerce tracking. So you could do something like this:
<script type="text/javascript">
	var transdata = {
		'addTrans':{
		'order_number':'{{ order_number }}',
		'shop_name':'{{ shop.name }}',
		'total_price':'{{ total_price | money_without_currency }}',
		'tax_price':'{{ tax_price | money_without_currency }}',
		'shipping_price':'{{ shipping_price | money_without_currency }}',
		'city':'{{ billing_address.city }}',
		'state':'{{ billing_address.province }}',
		'country':'{{ billing_address.country }}'
		},
		'addItems':[
		{% for line in line_items %}
		{   
		'trans_id':'{{ order_number }}',           // transaction ID - required
		'sku_code':'{{ line.title }}',           // SKU/code - required
		'prod_name':'{{ line.product.title }}',        // product name
		'category':'{{ line.product.type }}',   // category or variation
		'price':'{{ line.line_price | money_without_currency }}',          // unit price - required
		'quantity':'{{ line.quantity }}'               // quantity - required
		}
		{% if forloop.last != true %}
		,	
		{% endif %}
		{% endfor %}	
		]
	};
	</script>

such that the variable transdata collects the transaction variables to be used later. 

  • Next you need to set up GA within Shopify such that it tracks on all pages. So here is where the flexibility of Shopify's system comes in - when you add standard GA code to the /admin/settings/general Google Analytics section, Shopify grabs the UA code and adds custom code to the GA script. It also allows you to add ADDITIONAL JS code under a new section called Additional Google Analytics Javascript

    This section is the key to the customisation.
    This script supplements any tracking code you have added as part of standard GA implementation. Here JS can be added to all pages - including checkout.shopify.com making cross domain tracking possible. You could in theory add extra GA code (like additional trackers) here and it will load on every page (including checkout.shopify.com). If you added Universal Analytics to the standard GA analytics box you could now add traditional analytics code to supplement the Universal Analytics account.

    SIDENOTE - The below is an example - I can't guarantee it necessarily works out of the box. It is assuming you added traditional Google tracking code to /admin/settings/general Google Analytics section and want to track another secondary traditional Google Analytics account. The below would ordinarily be added to the "Additional Google Analytics Javascript" section
    var _gaq = _gaq || [];
      _gaq.push(['t2._setAccount', 'UA-xxxxxxxxx-2']);
      _gaq.push(['t2._setDomainName', 'none']);
      _gaq.push(['t2._setAllowLinker', true]);
      	
    	if (location.hostname == 'checkout.shopify.com'){
    	
    	var patharray = location.pathname.split('/');
    	
    	if(patharray[1] == 'carts'){
    	
    	if(patharray[4] != undefined){
    
    	var currpage = '/checkout/carts/'+patharray[4]; 
    	
    	}else{
    	
    	var currpage = '/checkout/carts/show'; 
    	
    	}
    	}else if(patharray[1] == 'orders'){
    	
    	if(patharray[4] != undefined){
    	var currorder = patharray[4].split('?');
    	
    	if(currorder[0] == 'pay'){
    	
    	var currpage = '/checkout/orders/pay'; 
    	
    	}else if(currorder[0] == 'processing'){
    	
    	var currpage = '/checkout/orders/processing'; 
    	
    	}else{
    	var currpage = '/checkout/orders/'+currorder[0];
    	}
    	
    	}else{
    	var currpage = '/checkout/orders/show'; 
    	}
    	
    	}
    	
            _gaq.push(['t2._trackPageview',currpage]);
    
            	
    	if(currpage == '/checkout/orders/show' && typeof(transdata) != undefined){
    	console.log(transdata);
    	
    	_gaq.push(['t2._addTrans',
        transdata['addTrans']['order_number'],           // transaction ID - required
        transdata['addTrans']['shop_name'],  // affiliation or store name
        transdata['addTrans']['total_price'],          // total - required
        transdata['addTrans']['tax_price'],           // tax
        transdata['addTrans']['shipping_price'],              // shipping
    	transdata['addTrans']['city'],       // city
        transdata['addTrans']['state'],     // state or province
        transdata['addTrans']['country']             // country
    	]);
    		
        for(var trans_item = 0; trans_item < transdata['addItems'].length; trans_item++){
        _gaq.push(['t2._addItem',
        transdata['addTrans']['order_number'],           // transaction ID - required
        transdata['addItems'][trans_item]['prod_name'],           // SKU/code - required
        transdata['addItems'][trans_item]['prod_name'],        // product name
    	transdata['addItems'][trans_item]['category'],   // category or variation
        transdata['addItems'][trans_item]['price'],          // unit price - required
        transdata['addItems'][trans_item]['quantity']// quantity - required
        ]);
    
        } 
        _gaq.push(['t2._trackTrans']); 
    	
    	}
    
            }else{
    	  _gaq.push(['t2._trackPageview']);
    	}
    
    
    
    (function(){
    
              function addListener(element, type, callback) {
                if (element.addEventListener) {
                  element.addEventListener(type, callback);
                }
                else if (element.attachEvent) {
                  element.attachEvent('on' + type, callback);           
                }
              }
              function decorate(event) {
                event = event || window.event;
                var target = event.target || event.srcElement;
                if (target && (target.action || target.href)) {
    
    				if(_gaq != undefined && target.action != undefined){
    					
    					var pageTracker = _gat._getTrackerByName(); // Gets the default tracker.
    					var linkerUrl = pageTracker._getLinkerUrl(target.action);
    					
    					target.action = linkerUrl;
    					
    				}else if(_gaq != undefined && target.href != undefined){
    					
    					var pageTracker = _gat._getTrackerByName(); // Gets the default tracker.
    					var linkerUrl = pageTracker._getLinkerUrl(target.href);
    					
    					target.href = linkerUrl;					
    					
    				}				
    
                }
              }
              addListener(window, 'load', function(){
                for (var i=0; i<document.forms.length; i++) {
                  if(document.forms[i].action && document.forms[i].action.indexOf('/cart') >= 0) {
                    addListener(document.forms[i], 'submit', decorate);
                  }
                }
                for (var i=0; i<document.links.length; i++) {
                  if(document.links[i].href && document.links[i].href.indexOf('/checkout') >= 0) {
                    addListener(document.links[i], 'click', decorate);
                  }
                }
              })
       }());
    Ok so for those familiar with JS and are slightly offended by weird if statements ... I'm really sorry. Essentially what the script is doing is trying to figure out whether the page is currently on checkout.shopify.com, whether the URL is a cart or order page, make the URLs friendly if they are too long for GA, add ecommerce tracking code by interpreting our variable transdata if it is a confirmation page, and then finally (!) there is a script (borrowed from the Shopify Universal Analytics beta test) that passes cookie data via URL for the traditional GA. If you added traditional GA to the Google Analytics section then you probably don't need it as the cookie data will have passed. If you did add Universal analytics code to the /admin/settings/general Google Analytics section then you might also like to add this:
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl'; : 'http://www';) + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
    Which is the standard way of calling the ga.js code.

​So... in theory you can actually customize GA code alot ... like ALOT alot ... but its all theory and there are undoubtedly problems with customisation. The above is literally just an example. If you are using Universal Analytics get yourself on the Shopify beta testing as it does seem to work. 

Hope this was helpful to someone.. also if its just plain wrong advice let me know..!

A Positive10 Peep
0 Likes
Highlighted
New Member
1 0 0

Hello Michael,

 

I have been experiencing the same problem as Lolo, and I read through the steps that you suggested. Here is what I did, and what subsequently happened: 

 

I added the JS provided by you to the 'additional content and scripts'

I then added the JS to the 'additional GA javascript' where I added my own UA number in the second line

Just below that I added the third block of JS, because I am using UA and per your recommendation.

 

Following these saved changes, I did two test runs on purchasing items from my website via google ad words campaigns. Not only was I NOT able to track the conversions from the original source, the conversions did not populate in my GA AT ALL. 

 

If you have any insight, I would thoroughly appreciate it. This problem has been hampering my business for some time now, and I need to get it squared away. 

 

Thanks 

0 Likes
Highlighted
Shopify Partner
52 0 7

Hi Jay,

I've mailed you direct but I've also noticed that some of the code above is wrong - specifically the traditional GA code 

----

(function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl';; : 'http://www';;) + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();

-----

The bolded sections should not have a semicolon (;) at the end. I have a feeling that the code editor added them so they should be deleted. 

That said the script is ecommerce tracking enabled for a second Google Analytics user account in addition to the one you may have already set up.

If you want to enable ecommerce on Universal Analytics then you might have to make a request to Aaron at Shopify to be put on the beta for Universal Analytics which should enable ecommerce tracking. 

A Positive10 Peep
0 Likes
Highlighted
New Member
3 0 0

Wanted to add that Google's Universal Analytics DOES include e-commerce tracking (as of April 2014).  It is now out of beta and will eventually become the standard that all GA users will have to upgrade/transition to.

Shopify may not have integrated all of the new Universal tools into their code yet, but we have Universal working great for our store and I'd rather learn the new features now to get a head start.

Goals and funnels are fairly easy to set up and Shopify has good instructions here: http://docs.shopify.com/support/other/general-information/google-analytics-goals-and-funnels

0 Likes
Highlighted
New Member
3 0 0

I have a question for cross-domain tracking. It would be great if I got a response/clarification from a Shopify employee.

On Gihub we have for Universal Analytics we have the code for proper cross-domain tracking:  https://gist.github.com/aSadhankar/6d8e7272379d033ecaa3 ;

However, (and that's my question), we don't see in the code above anything related in terms of transactional data (e.g price, tax, city etc). 

Do we need to need any extra code with transactional data in the code that we have in the Github? Or the code that is in the Github includes transactional data? 

That's why what I did, is to transactional data (from Universal Analytics) and the code as provided by Shopify on Github. 


 <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-XXXXXXXX-X', 'auto', {'allowLinker': true});ga('send', 'pageview');
        (function(){
          ga('require', 'linker');
          function addListener(element, type, callback) {
            if (element.addEventListener) {
              element.addEventListener(type, callback);
            }
            else if (element.attachEvent) {
              element.attachEvent('on' + type, callback);
            }
          }
          function decorate(event) {
            event = event || window.event;
            var target = event.target || event.srcElement;
            if (target && (target.action || target.href)) {
              ga(function (tracker) {
                var linkerParam = tracker.get('linkerParam');
                document.cookie = '_shopify_ga=' + linkerParam + ';';
              });
            }
          }
          addListener(window, 'load', function(){
            for (var i=0; i<document.forms.length; i++) {
              if(document.forms[i].action && document.forms[i].action.indexOf('/cart') >= 0) {
                addListener(document.forms[i], 'submit', decorate);
              }
            }
            for (var i=0; i<document.links.length; i++) {
              if(document.links[i].href && document.links[i].href.indexOf('/checkout') >= 0) {
                addListener(document.links[i], 'click', decorate);
              }
            }
          })
        }());

ga('create', 'UA-xxxxxxxx-x', 'yourdomain.com');
    ga('send', 'pageview');
    ga('require', 'ecommerce', 'ecommerce.js');

    function trackEcommerce() {
    this._addTrans = addTrans;
    this._addItem = addItems;
    this._trackTrans = trackTrans;
    }
    function addTrans(orderID,store,total,tax,shipping,city,state,country) {
    ga('ecommerce:addTransaction', {
        'id': orderID,
        'affiliation': store,
        'revenue': total,
        'tax': tax,
        'shipping': shipping,
        'city': city,
        'state': state,
        'country': country
    });
    }
    function addItems(orderID,sku,product,variation,price,qty) {
    ga('ecommerce:addItem', {
        'id': orderID,
        'sku': sku,
        'name': product,
        'category': variation,
        'price': price,
        'quantity': qty
    });
    }
    function trackTrans() {
        ga('ecommerce:send');
    }
    var pageTracker = new trackEcommerce()
  </script>

 

So on Github does the code include transactional data or do we have to include the transactional data manually? 

Thank you! 

 

 

 

0 Likes
Highlighted
Shopify Partner
52 0 7

Hi,

Not a Shopify employee but have a fair bit of experience now. The Github code allows for cross domain tracking only. The transactional information is handled by enabling standard GA in Shopify (i.e. via the dashboard). In fact the Github code is also added as default when users use the dashboard.

Are you having issues tracking ecommerce when using the standard GA implementation?

Cheers,

Mike

A Positive10 Peep
1 Like
Highlighted
New Member
3 0 0

Hi Mike,

 

Thank you for your immediate response. 

There are no problems tracking e-commerce when I am using the standard GA implementation (but there was no appearance of transactional data on Google Analytics) and I guessed it was some kind of problem with the code on Github (and wanted something extra in terms of code for transactional data).

But everything now seems to be working fine and now the transactional data seem to appear also on Google Analytics! 

0 Likes
Highlighted
Shopify Partner
52 0 7

No worries! 

You can use the additional script area relating to the thank you page if you need to track ecommerce outside of the standard implementation (for example if you are using a different analytics provider or tracking system). However going down the standard implementation route is typically the best.

Glad to hear it is all working!

A Positive10 Peep
1 Like