Shopify: Fix your Google Analytics Product Performance Reports

The Problem: By default Shopify includes product variant details in the product’s name when it sends e-commerce data to Google Analytics, . If you sell clothing ,or shoes, or other products with color and size variants, then your Product Performance Report becomes too granular.

ga-productperformance-productname

How Shopify data shows up by default in Google Analytics. Notice that the various “Trillium Parka” variants are ungrouped because the size and color information is in the product name. This makes it difficult to see aggregate data for all variants of this product.

This is a bug, because there already exists a “Product Variant” field in Analytics, and it is already being properly populated.

The Solution:
Google Analytics Custom Data Import

The solution to this problem is to overwrite the Shopify data using the Custom Data Import tool.

Step 1: Export your Product Data

First we need to export all our product data – you can use a similar technique to generating your own custom Google Shopping Product Feeds to build a CSV export file.

a. Create a new Collection Template

Call the new collection template csv-ga-product-feed and paste the following code:

{% layout none %}{% paginate collection.products by 1000 %}ga:productSku,ga:productName,ga:productVariant{% for product in collection.products %}{% for variant in product.variants %}
{{ variant.sku }},{{ product.title | replace: ',','' }},{{variant.title | replace: ',',''}}{% endfor %}{% endfor %}{% endpaginate %}

(also available on GitHub here)

b. Create a new Collection based on your csv-ga-product-feed Template

Select the products you want to include in this feed (probably all your products). These will be the products whose values will be overwritten in Google Analytics. Call your collection “Google Analytics Product Data Import” or something similar and save it.

c. Download your Product Feed

  • View your new collection in your store (eg: store.myshopify.com/collections/google-analytics-product-data-import)
  • View source in your browser and save as HTML
  • Rename the file with a CSV extension (eg: google-analytics-product-data-import.csv)

Step 2: Setup and Import the data into Google Analytics

IMPORTANT WARNING! I highly recommend you duplicate or backup your Google Analytics view and do a trial run before working with your live data. Once you upload this new data and overwrite there is no UNDO!

a. Setup the Data Feed

  • Go to Google Analytics > Admin > Account > Property > Data Import
  • Click the red “+ NEW DATA SET” button
  • Select “Product Data”
  • Give your Data Import a name: “Product Name Override”
  • Select the Google Analytics Views you want this import to affect
  • Setup your Data Set Schema: Product SKU is the mandatory key, but select Product and Product Variant as the additional fields.
  • Overwrite Hit Data: Choose Yes (but read my warning above)
  • Click Save and Done

b. Upload your data feed

  • Click on “manage uploads” beside your new Data Feed definition
  • Click the blue UPLOAD button
  • Choose your CSV file and click UPLOAD again
  • And now wait for the upload an update to be complete

Step 3: Verify your new data

The data upload will only affect data from this date forward. So your old data will unfortunately not be fixed. But your future data will be nice and clean.

You will need to wait at least a day before you start seeing the new data coming in. If you add new product SKUs to your store, you will also need to regenerate and reupload a new file in order for the new product data to be fixed.

Shopify Cancelled Orders and Google Analytics

By default, when you cancel an order in Shopify, that transaction remains as positive revenue in your Google Analytics.

To “cancel” the transaction in Google Analytics you have to send a negated version of the transaction. To do this in Shopify you have to create a Webhook on Order Cancelled that hits a script (located on the same root domain as your store) that will call server side Google Analytics e-commerce code to negate the transaction.

Webhook Endpoint Dependencies

Details

Place the following code into a file that will act as your Order Cancelled Webhook endpoint (ie: www2.mydomain.com/webhooks/order-cancelled.php).

Make sure you:

  • Update the script to use your GA Account Id and Root Domain.
  • Change the path of autoload.php to point at your php-ga library

Begin Code

<?php
use UnitedPrototype\GoogleAnalytics;
require_once '../includes/autoload.php'; // Update to point at your php-ga install

$GA_AccountId = 'UA-********-1'; // Update with your GA account
$GA_domain = 'mystore.ca'; // Update with your root domain
$webhookContent = '';
// Read the webhook content
$webhook = fopen('php://input' , 'rb');
while (!feof($webhook)) {
  $webhookContent .= fread($webhook, 4096);
}
fclose($webhook);

if (!empty($webhookContent)) {
  // Convert the webhook content into an array
  $shopifyOrder = json_decode($webhookContent, true);

  // START GOOGLE ANALYTICS
  $tracker = new GoogleAnalytics\Tracker($GA_AccountId, $GA_domain);

  $visitor = new GoogleAnalytics\Visitor();
  $visitor->setIpAddress($_SERVER['REMOTE_ADDR']);
  $visitor->setUserAgent($_SERVER['HTTP_USER_AGENT']);
  $visitor->setScreenResolution('1024x768');

  $session = new GoogleAnalytics\Session();

  $page = new GoogleAnalytics\Page($_SERVER['REQUEST_URI']);
  $page->setTitle('Order Cancelled');

  $tracker->trackPageview($page, $session, $visitor);

  $transaction = new GoogleAnalytics\Transaction();
  $transaction->setOrderId($shopifyOrder['name']);
  $transaction->setAffiliation('');
  $transaction->setTotal(-$shopifyOrder['total_price']);
  $transaction->setTax(-$shopifyOrder['total_tax']);
  $transaction->setShipping(-$shopifyOrder['shipping_lines'][0]['price']);
  $transaction->setCity($shopifyOrder['billing_address']['city']);
  $transaction->setRegion($shopifyOrder['billing_address']['province']);
  $transaction->setCountry($shopifyOrder['billing_address']['country']);

  foreach ( $shopifyOrder['line_items'] as $product ) {
    $item = new GoogleAnalytics\Item();
    $item->setOrderId($shopifyOrder['name']);
    $item->setSku($product['sku']);
    $item->setName($product['title']);
    $item->setVariation('');
    $item->setPrice($product['price']);
    $item->setQuantity(-$product['quantity']);
    $item->validate();
    $transaction->addItem($item);
  }
  $transaction->validate(); 

  $tracker->trackTransaction($transaction, $session, $visitor);
  // END GOOGLE ANALYTICS
}
?>

Setup the Webhook in Shopify

In your Admin dashboard go to:

  • Settings > Notifications > Webhooks (at the bottom)
  • Create a Webhook
  • Event: Order Cancellation // Format: JSON // URL: The full url of your php file

Test

  • Google Analytics: Got to the Real Time > Content report
  • Shopify: Click “Send test notification” link beside your webhook.
  • Google Analytics: You should see a page request popup with your script name
  • Google Analytics: Wait a few hours and then (for transactions to register) and then go to Conversions > Ecommerce > Product Performance and you should see a sledge-hammer and wire-cutter products (the Shopify sample data) along with negative quantities and value.

Further Reading & Resources

Google Analytics Custom Events to Simplify Navigation

Below, is a screen shot of a quiz from our online ATV safety course.

ATV Quiz

The navigation is relatively simple:

  • NEXT and PREVIOUS buttons
  • Right hand menu to navigate to any question
  • FINISH QUIZ button that becomes visible once you have answered all the questions

Questions About Usability:

  • Does anyone actually use the PREVIOUS button?
  • Does anyone actually use the side menu to Navigate?

To answer these questions you can setup a series of Google Analytics Custom Events on each button/nav click.

onclick=”_gaq.push([‘_trackEvent’, ‘TDE Navigation’, ‘Next’, ‘Quiz’]);”

WARNING! Google Analytics has a data limit of 500 hits per session (this includes page views, events, and other types of data). Tracking EVERYTHING with custom events could cause you to reach those limits.

Looking at Google Analytics

Total Events

Total events will give an indication of the relative usage of each navigation element

Unique Events

Unique events will give us an idea of navigation usage PER SESSION.  This answers the question “How many users click on the navigation element at least once during a visit”.

The verdict

  • The previous button only receives 1.3% of the total navigation clicks.
  • About 1 in 6 users do click previous at some point in their quiz.

RECOMMENDATION: Previous button should be converted to a simple text link

  • The side menu (Jump) only receives 0.2% of total navigation clicks.
  • Only 3.5% of users ever used the side menu (about 1 in 30 users).

RECOMMENDATION: Remove the side navigation menu all together
(or make it a slide in/out style navigation element)

Next Steps

Consider auto-advancing to the next question when an answer choice is clicked

Not surprisingly, almost 92% of total navigation clicks go to the NEXT button and another 6.5% of total clicks are on the finish button.  So over 98% of the time the user simply wants to advance to the next logical step.

Does this mean that we should we just auto-advance to the next question when the user selects the answer choice? How often does a user change his answer choice before clicking the next button?  The answer to this last question will be saved for another post (after we collect more data)

I hope you found this post useful.  If you know of simpler methods to gain this sort of insight, please post them in the comments below.

Which Social Networks Are Your Visitors Logged Into

Back in February 2012, Tom Anthony wrote a couple of great posts on how to detect if visitors were logged into a social network and then how to use Google Analytics to track this information.

After the post, there was some discussion about how there are only 5 CustomVar slots in the standard version of Google Analytics, and how it would be nice to consolidate all the Social Media logged in statuses into a single Custom Var.

Well here is the code and steps to track them all in a single Custom Var slot

To implement this using Universal Analytics please read Mark Hoad’s post here: http://aberrant.me/cool-google-analytics-hacks-using-the-new-universal-analytics-js/

1. Read Tom Anthony’s Posts

2. Install The New JavaScript Code

Put this in your <HEAD>

Download the above code here

Then add the following to the bottom of the page, before the closing </BODY> tag:

Download the above code here

NOTE 1: Remember to replace Your-App-Id with your Facebook App Id and http://www.yourdomain.com/pixel.png with a url to an image on your website.  (This last line can probably be implemented with just an in-line JavaScript call, but I’m posting this code as-is because it “Works on My Site”)

NOTE 2: The code above is configured to log your Social Traffic login status in Custom Variable Slot 5.  Change this number if you want a different slot.

3. Setup Custom Segments

If you setup the code above properly, you should see data similar to this in your Analytics Account under the appropriate CustomVar (#5 in our case):

What you want to do is setup Custom Segments so you can isolate individual networks when the user is logged into multiple networks at the same time.  This is very similar to how it was done in the original post, but here are the screen shots for the 4 networks tracked:

Facebook

Google Plus

Gmail/Google Login

Twitter

4. View Data in Analytics

Choose your custom segments:

View your beautiful data!

          Beautiful Social Data 2

(Note: We had a bug with our Facebook tracking when we initially set this up – hence the strange zero-to-hero traffic spike with Facebook towards the end of the graph)

WordPress Plugins

There are already 2 (that I know of) WordPress plugins that implement Tom Anthony’s initial code:

  1. Adapt Partners Social Media User Detection WordPress Plugin
  2. Springest’s Social Analytics WordPress Plugin

I assume it’s just a matter of time before they update their code to be able to cram the tracking into a single CustomVar (although for those already using the old way using multiple CustomVars you will probably want to adjust your Custom Segments to include an OR clause in order to report on data from both formats).

Additional Credits…

A huge thank you to Tom Anthony for the original code that triggered this and to our dev team at Fresh Air Educators, Inc for extending and implementing this new feature!