Enhanced Ecommerce for Tag Manager

This guide describes how to implement Universal Analytics Enhanced Ecommerce features using Google Tag Manager on a website.

Overview

Google Analytics Enhanced Ecommerce enables product impression, promotion, and sales data to be sent with any of your Google Analytics pageviews and events. Use pageviews to track product impressions and product purchases; and use events to track checkout steps and product clicks.

Before you Begin

We recommend reviewing the Enhanced Ecommerce Data Types and Actions section of the Enhanced Ecommerce Dev Guide to help you plan your implementation. The guide will help you understand which fields are required and optional for each of the ecommerce interactions you want to measure.

Enabling Enhanced Ecommerce

In most implementations, you should enable Enhanced Ecommerce on each of your Universal Analytics pageview or event tags. You have two options for enabling Enhanced Ecommerce in the tag editor screen of the web interface:

  • Implement using the Data Layer (Recommended)
  • Implement using a Custom JavaScript Macro

Although both methods provide equivalent ecommerce functionality, we recommend all websites that support a data layer use the Data Layer method. This guide presents the Data Layer method as the default, while Using a Custom JavaScript Macro is documented at the end of this guide.

Using the Data Layer

The following sections will show you how to use the data layer to measure the following enhanced ecommerce activities:

Clearing the ecommerce object

It's recommended that you use the following command to clear the ecommerce object prior to pushing an ecommerce event to the data layer. Clearing the object will prevent multiple ecommerce events on a page from affecting each other.

dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.

Measuring Product Impressions

  • Ecommerce Measurement: impressions
  • Accepts Data: array of impressionFieldObjects

Measure product impressions by using the impression action and one or more impressionFieldObjects. The following example assumes details about the products displayed on a page are known at the time the page loads:

<script>
// Measures product impressions and also tracks a standard
// pageview for the tag configuration.
// Product impressions are sent by pushing an impressions object
// containing one or more impressionFieldObjects.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'currencyCode': 'EUR',                       // Local currency is optional.
    'impressions': [
     {
       'name': 'Triblend Android T-Shirt',       // Name or ID is required.
       'id': '12345',
       'price': '15.25',
       'brand': 'Google',
       'category': 'Apparel',
       'variant': 'Gray',
       'list': 'Search Results',
       'position': 1
     },
     {
       'name': 'Donut Friday Scented T-Shirt',
       'id': '67890',
       'price': '33.75',
       'brand': 'Google',
       'category': 'Apparel',
       'variant': 'Black',
       'list': 'Search Results',
       'position': 2
     }]
  }
});
</script>

Measuring Product Clicks

  • Ecommerce Measurement: click
  • Accepts Data: list, array of productFieldObjects

Measure clicks on product links by pushing a click action to the data layer, along with a productFieldObject to represent the clicked product, as in this example:

<script>
/**
 * Call this function when a user clicks on a product link. This function uses the event
 * callback datalayer variable to handle navigation after the ecommerce data has been sent
 * to Google Analytics.
 * @param {Object} productObj An object representing a product.
 */
function(productObj) {
  dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
  dataLayer.push({
    'event': 'productClick',
    'ecommerce': {
      'click': {
        'actionField': {'list': 'Search Results'},      // Optional list property.
        'products': [{
          'name': productObj.name,                      // Name or ID is required.
          'id': productObj.id,
          'price': productObj.price,
          'brand': productObj.brand,
          'category': productObj.cat,
          'variant': productObj.variant,
          'position': productObj.position
         }]
       }
     },
     'eventCallback': function() {
       document.location = productObj.url
     }
  });
}
</script>

Measuring Views of Product Details

  • Ecommerce Measurement: detail
  • Accepts Data: list, array of productFieldObjects

Measure a view of product details by pushing a detail action to the data layer, along with one or more productFieldObjects representing the products being viewed:

<script>
// Measure a view of product details. This example assumes the detail view occurs on pageload,
// and also tracks a standard pageview of the details page.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'detail': {
      'actionField': {'list': 'Apparel Gallery'},    // 'detail' actions have an optional list property.
      'products': [{
        'name': 'Triblend Android T-Shirt',         // Name or ID is required.
        'id': '12345',
        'price': '15.25',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Gray'
       }]
     }
   }
});
</script>

Measuring Additions or Removals from a Shopping Cart

  • Ecommerce Measurement: add, remove
  • Accepts Data: list, array of productFieldObjects

Similarly, you can measure additions or removals from a shopping cart using an add or remove actionFieldObject and a list of productFieldObjects:

Adding a Product to a Shopping Cart

// Measure adding a product to a shopping cart by using an 'add' actionFieldObject
// and a list of productFieldObjects.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'event': 'addToCart',
  'ecommerce': {
    'currencyCode': 'EUR',
    'add': {                                // 'add' actionFieldObject measures.
      'products': [{                        //  adding a product to a shopping cart.
        'name': 'Triblend Android T-Shirt',
        'id': '12345',
        'price': '15.25',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Gray',
        'quantity': 1
       }]
    }
  }
});

Removing a Product from a Shopping Cart

// Measure the removal of a product from a shopping cart.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'event': 'removeFromCart',
  'ecommerce': {
    'remove': {                               // 'remove' actionFieldObject measures.
      'products': [{                          //  removing a product to a shopping cart.
          'name': 'Triblend Android T-Shirt',
          'id': '12345',
          'price': '15.25',
          'brand': 'Google',
          'category': 'Apparel',
          'variant': 'Gray',
          'quantity': 1
      }]
    }
  }
});

Measuring Promotions

You can measure both impressions and clicks on internal site promotions, such as banners displayed on the site itself advertising a sale on a particular subset of products, or an offer for free shipping.

Measuring Promotion Impressions

  • Ecommerce Measurement: promoView
  • Accepts Data: array of promoFieldObjects

To measure a promotion impression, set the promoView key in your ecommerce data layer var to a promoFieldObject that describes the promotions displayed to users on the page:

<script>
// An example of measuring promotion views. This example assumes that
// information about the promotions displayed is available when the page loads.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'promoView': {
      'promotions': [                     // Array of promoFieldObjects.
       {
         'id': 'JUNE_PROMO13',            // ID or Name is required.
         'name': 'June Sale',
         'creative': 'banner1',
         'position': 'slot1'
       },
       {
         'id': 'FREE_SHIP13',
         'name': 'Free Shipping Promo',
         'creative': 'skyscraper1',
         'position': 'slot2'
       }]
    }
  }
});
</script>

Measuring Promotion Clicks

To measure a click on a promotion, push the promoClick action to the data layer with an array containing a promoFieldObject describing the clicked promotion:

<script>
/**
 * Call this function when a user clicks on a promotion. This function uses the eventCallBack
 * datalayer variable to handle navigation after the ecommerce data is sent to Google Analytics.
 *
 * @param {Object} promoObj An object representing an internal site promotion.
 */
function onPromoClick(promoObj) {
  dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
  dataLayer.push({
    'event': 'promotionClick',
    'ecommerce': {
      'promoClick': {
        'promotions': [
         {
           'id': promoObj.id,                         // Name or ID is required.
           'name': promoObj.name,
           'creative': promoObj.creative,
           'position': promoObj.pos
         }]
      }
    },
    'eventCallback': function() {
      document.location = promoObj.destinationUrl;
    }
  });
}
</script>

Measuring a Checkout

To measure each step in a checkout process you need to:

  1. Measure each step of the checkout process using the checkout action.
  2. If applicable, measure checkout options using the checkout_option action.
  3. Optionally set user-friendly step names for the checkout funnel report by configuring Ecommerce Settings in the Admin section of the web interface.

1. Measuring Checkout Steps

  • Ecommerce Measurement: checkout
  • Accepts Data: step, array of productFieldObjects

To measure the checkout process, which might include a checkout button and one or more checkout pages where users enter shipping and payment information, use the checkout action and the step field to indicate which stage of the checkout process is being measured. You can also use the option field to provide a piece of additional data about the page, such as the payment type that was selected by the user.

<script>
/**
 * A function to handle a click on a checkout button. This function uses the eventCallback
 * data layer variable to handle navigation after the ecommerce data has been sent to Google Analytics.
 */
function onCheckout() {
  dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
  dataLayer.push({
    'event': 'checkout',
    'ecommerce': {
      'checkout': {
        'actionField': {'step': 1, 'option': 'Visa'},
        'products': [{
          'name': 'Triblend Android T-Shirt',
          'id': '12345',
          'price': '15.25',
          'brand': 'Google',
          'category': 'Apparel',
          'variant': 'Gray',
          'quantity': 1
       }]
     }
   },
   'eventCallback': function() {
      document.location = 'checkout.html';
   }
  });
}
</script>

2. Measuring Checkout Options

  • Ecommerce Measurement: checkout_option
  • Accepts Data: step, option

The checkout option is useful in cases where you've already measured a checkout step but you want to capture additional information about the same checkout step. For example, the shipping method selected by a user. To measure this use the checkout_option action along with the step and option fields.

<script>
/**
 * A function to handle a click leading to a checkout option selection.
 */
function onCheckoutOption(step, checkoutOption) {
  dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
  dataLayer.push({
    'event': 'checkoutOption',
    'ecommerce': {
      'checkout_option': {
        'actionField': {'step': step, 'option': checkoutOption}
      }
    }
  });
}
</script>

3. Checkout Funnel Configuration

Optionally, each step in your checkout process can be given a descriptive name that will be used in reports. To configure these names, visit the Admin section of the Google Analytics Web Interface, select the view (profile) and click on Ecommerce Settings. Follow the Ecommerce set-up instructions to label each checkout step you intend to track.

Ecommerce setup in the Google Analytics admin interface. A checkout
         funnel is defined with four steps: 1. Review Cart, 2. Collect Payment
         Info, 3. Confirm Purchase Details, 4. Receipt.
Figure1: Ecommerce setup, checkout funnel.

Measuring Purchases

  • Ecommerce Measurement: purchase
  • Accepts Data: id (Transaction ID), array of productFieldObjects

Push your transaction details into the Data Layer using the purchase action, along with an event that will fire an enhanced ecommerce-enabled tag. In this example, the transaction details are known at the time the page loads, and will be sent with a pageview when the gtm.js script returns:

<script>
// Send transaction data with a pageview if available
// when the page loads. Otherwise, use an event when the transaction
// data becomes available.
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'purchase': {
      'actionField': {
        'id': 'T12345',                         // Transaction ID. Required for purchases and refunds.
        'affiliation': 'Online Store',
        'revenue': '35.43',                     // Total transaction value (incl. tax and shipping)
        'tax':'4.90',
        'shipping': '5.99',
        'coupon': 'SUMMER_SALE'
      },
      'products': [{                            // List of productFieldObjects.
        'name': 'Triblend Android T-Shirt',     // Name or ID is required.
        'id': '12345',
        'price': '15.25',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Gray',
        'quantity': 1,
        'coupon': ''                            // Optional fields may be omitted or set to empty string.
       },
       {
        'name': 'Donut Friday Scented T-Shirt',
        'id': '67890',
        'price': '33.75',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Black',
        'quantity': 1
       }]
    }
  }
});
</script>

Measuring Refunds

  • Ecommerce Measurement: refund
  • Accepts Data: id (Transaction ID), array of productFieldObjects

To measure a full refund of a transaction, push a refund actionFieldObject along with the transaction ID of the transaction being refunded:

<script>
// Refund an entire transaction by providing the transaction ID. This example assumes the details
// of the completed refund are available when the page loads:
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'refund': {
      'actionField': {'id': 'T12345'}         // Transaction ID. Required for purchases and refunds.
    }
  }
});
</script>

To measure a partial refund, add a list of productFieldObjects, including product IDs and quantities being refunded:

<script>
// Measure a partial refund by providing an array of productFieldObjects and specifying the ID and
// quantity of each product being returned. This example assumes the partial refund details are
// known at the time the page loads:
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'refund': {
      'actionField': {'id': 'T12345'},        // Transaction ID.
      'products': [
            {'id': 'P4567', 'quantity': 1},   // Product ID and quantity. Required for partial refunds.
            {'id': 'P8901','quantity': 2}
       ]
     }
  }
});
</script>

Passing Product-scoped Custom Dimensions

To pass a product-scoped custom dimension to the ecommerce object, use the following notation to add it to the product:

  dimensionn

where n is a natural number, for example:

<script>
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'purchase': {
      ...

      'products': [{
        'name': 'Triblend Android T-Shirt',
        'id': '12345',
        'price': '15.25',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Gray',
        'dimension1': 'Same day delivery'
       }]
     }
   }
});
</script>

Passing Product-scoped Custom Metrics

To pass a product-scoped custom metric to the ecommerce object, use the following notation to add it to the product:

  metricn

where n is a natural number, for example:

<script>
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'purchase': {
      ...

      'products': [{
        'name': 'Goal Flow Garden Hose',
        'id': 'p001',
        'brand': 'Google Analytics',
        'category': 'Home Goods',
        'variant': 'Green',
        'price': '20',
        'quantity': 1,
        'metric3': '10'  // Custom metric 'Cost'
       }]
     }
   }
});
</script>

Combining Impressions and Actions

In cases where you have both product impressions and an action, it is possible to combine and measure them in a single hit.

The example below shows how to measure a product detail view with product impressions from a related products section:

<script>
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object.
dataLayer.push({
  'ecommerce': {
    'impressions': [
     {
       'name': 'Triblend Android T-Shirt',        // Name or ID is required.
       'id': '12345',
       'price': '15.25',
       'brand': 'Google',
       'category': 'Apparel',
       'variant': 'Gray',
       'list': 'Related Products',
       'position': 1
     },
     {
       'name': 'Donut Friday Scented T-Shirt',
       'id': '67890',
       'price': '33.75',
       'brand': 'Google',
       'category': 'Apparel',
       'variant': 'Black',
       'list': 'Related Products',
       'position': 2
     }],
    'detail': {
      'actionField': {'list': 'Apparel Gallery'},  // 'detail' actions have an optional list property.
      'products': [{
        'name': 'Triblend Android T-Shirt',       // Name or ID is required.
        'id': '12345',
        'price': '15.25',
        'brand': 'Google',
        'category': 'Apparel',
        'variant': 'Gray'
       }]
     }
  }
});
</script>

Using a Custom JavaScript Macro

If your website does not support a data layer, you can use a custom JavaScript macro to call a function that returns the ecommerce data object. This object should use the data layer syntax shown earlier in this guide, for example:

// A custom JavaScript macro that returns an ecommerceData object
// that follows the data layer syntax.
function() {
  var ecommerceData = {
    'ecommerce': {
      'purchase': {
        'actionField': {'id': 'T12345'},
        'products': [
            // List of productFieldObjects
        ],
        ... // Rest of the code should follow the data layer syntax.
     }
  };
  return ecommerceData;
}

If you choose to use a custom JavaScript macro instead of the data layer, select Enable Enhanced Ecommerce Features and set the Read data from macro option.