Optimizing Google Enhanced eCommerce for Magento

Here at Demac Media, our in-house conversion optimization team specializes in utilizing Google’s suite of analytics and eCommerce tools to ensure that our clients see the best return from their customers’ interactions with their online storefronts.

Recently, Google upgraded their Classic Analytics tracking code to the new Universal Analytics feature set, which improves the way data is collected and organized to provide you with a more in-depth, flexible, and thorough understanding of how your users interact with your online content across multiple devices.  In addition, this update also launched support for Google’s Enhanced eCommerce plug-in, which you can learn more about through our article released last fall.

Enhanced eCommerce Analytics

conversion

With Enhanced eCommerce, you can now analyze your users’ shopping and purchasing behaviour, product attribution, the success of your marketing efforts, and the economic performance of your products.  It enables you to examine how your customers interact with your product offerings through product impressions, product clicks, viewing product details, adding an item to their shopping cart, initiating the checkout process, transactions, and refunds – identifying customer segments based on recognized personas, user characteristics, and behaviour.  By providing insight into a customers’ path to purchase, you have a treasure trove of valuable information at your fingerprints.

Universal Analytics and Enhanced eCommerce are the essential tools that we use on the Magento stores that we build.  We implement these tools by installing “Google Enhanced eCommerce for Magento” module, which is the official extension for adding Google Universal Analytics and Enhanced eCommerce to your Magento store.

Related: Testing Google’s Enhanced eCommerce Analytics on Magento

Not Perfect

While the official module eases the process of setting up a Magento site to take advantage of Google’s offerings, we found that the official extension was not perfect.  The impression data reported did not adhere to the standards that we expect and recommend using (such as using the product SKU instead of its ID, or recording the use of a special price or discount).  In addition, we found that the module did not record every impression of a click on a product’s “Add to Cart” button.  Lastly, and most egregious, the installation and use of the active module burdened us with performance issues, directly impacting usability of the store for customers.

The Good News

These issues can be corrected with a couple of lines of revised code, which we will proceed to outline here.  It is recommended that you create a new module that rewrites classes from the existing official module so that you can safely apply the patches while maintaining the integrity and upgradability of the original module without directly changing its files.

UniversalAnalytics_Helper_Data

As previously mentioned, we prefer to track using a product’s SKU rather than it’s ID as the SKU is often visible and searchable in the frontend of the store.  It is unique to a product, while the ID is unique to that product’s representation within the Magento installation.  The SKU may also be used in a corresponding ERP system, while the Magento ID is not.  Furthermore, the Google API allows for either the ID or the SKU to be provided as a value.  As such, we rewrote the getTranslation() function of the Helper class as follows:

<?php
/**
* Get translation values from Config Defaults
*
* @param $part
*
* @return mixed
*/
public function getTranslation($part)
{
$translation = Mage::getStoreConfig('baua/translation/' . $part);
// Change our translation dependant on the part type as we cannot hack in config.xml
switch ($part) {
case 'addImpression':
case 'addProduct':
$translation['id'] = 'sku';
break;
case 'transaction':
if (isset($translation['entity_id']) && $translation['entity_id']) {
unset($translation['entity_id']);
}
$translation['increment_id'] = 'id';
break;
}
return $translation;
}

Here, we are setting the value of the ‘id‘ field on the Impression and Product data to use the product’s SKU.  However, we do maintain the Magento ID for our records by the addition of an ‘increment_id‘ field on the transaction actions, which replaces the previous ‘entity_id’ which served the same purpose.

UniversalAnalytics_Model_Monitor

<?php
/**
* @return string
*/
protected function generateProductClickList()
{
$text = '';
$urlList = Array();
foreach ($this->productImpressionList as $listName => $listItem) {
foreach ($listItem as $url => $item) {
...
// Change the onclick targeting to what we're using in EE
$text .= $this->JS->attachForeachObserve(
'button[onClick*="productAddToCartForm.submit(this)"]',
$currency . $product . $action . $send
);
...
}
}
return $text;
}

In our rewritten generateProductClickList() function of the Monitor model class, we ensure that the onClick targeting will trigger on each attempt of a user to add an item to their cart – in addition to tracking when that path is successful, as already supported by the official module.  This enables us to see user intent, judge the appeal of the calls to action present on the site, and pin point when customers “fall off” the purchasing path.

<?php
/**
* Add generate an array of product data
*
* @name generateProductData
*
* @param Mage_Sales_Model_Quote_Item $item
*
* @return array|null
*/
public function generateProductData($item)
{
$product = Mage::getModel('catalog/product')->load($item->getProductId());
if ($product->getVisibility() == 1) return null;
$order = Mage::getModel('sales/order')->load($item->getOrderId());
$productOptions = $item->getProductOptions();
// Allow for the discounted price to show instead of regular price
$product->setPrice($item->getBaseRowTotal());
$productData = $this->parseObject($product, 'addProduct');
$itemData = $this->parseObject($item, 'addProduct');
$itemData['variant'] = $this->extractAttributes($productOptions);
// Add in the SKU for our purposes
$itemData['id'] = $product->getSku();
return array_merge($productData, $itemData);
}

Furthermore, we rewrite the generateProductData() function to again use the product’s SKU instead of the Magento-supplied ID.  We also set the price of the product, before it is parsed, to the base row total to account for any discount and taxes on the product.  Effectively, we’re using the final sale price instead of the retail price.

UniversalAnalytics_Observer

<?php
/**
* @param $observer
*/
public function viewProductCollection($observer)
{
// Do not do this if we're in the admin or API
if (Mage::app()->getStore()->isAdmin()) return;
...
}
/**
* @param $observer
*
* @return null
*/
public function viewProduct($observer)
{
// Do not do this if we're in the admin or API
if (Mage::app()->getStore()->isAdmin()) return;
...
}

In our extension of the Observer class, we have rewritten the viewProductCollection() and viewProduct() functions to immediately abort if executed on the admin store. These functions run when a product is viewed or a product collection is accessed.  This can be an especially intensive task when editing product in the Magento Admin Panel or running an integration job through the Magento API as product objects and collections are used – without these return statements added to the start of the functions, our site performance was unknowingly impacted while these actions were performed.  In addition, neither action should be tracked by Google analytics as they are not customer or end-user facing.


Optimize your Store

enhanced ecommerce analytics

Through Google’s Universal Analytics, Enhanced eCommerce plugin, the official Magento module, and our recommended module fixes, we hope that you’ll find implementing these tools on your store to be beneficial and provide valuable information to help you remain profitable and competitive.

Related: Enhanced eCommerce for Google Analytics: How Does it Work?