Tracking True Product Impressions with Google Analytics Enhanced Ecommerce

Matt Redford,

Update: An improved and more refined tracking method of tracking impressions (including enhanced ecommerce) within Google Analytics can be found here.


Google Analytics enhanced ecommerce expands traditional sales tracking to include shopping activity relating to products, promotions and the checkout process.

One aspect of this is product impressions. In a common setup this will push individual products as ‘product views’ into Google Analytics on category pages. Pairing this with click data provides product CTR (click through rate) which can be used to monitor product popularity and provide insight to improve the shopping experience.

product impressions example
impression ga data


The traditional solution to this is to push all impressions at once on the page load. In some instances this is flawed because not all impressions are true because one of more products may not actually be viewable to the user.

Tracking true impressions has always been quite experimental from a development perspective but the recent release of 'IntersectionObserver' into Chrome 51 looks to address this. This allows you to monitor the current visibility of selected elements. A polyfill is available to make this functionality available to other browsers.

Using 'IntersectionObserver' I’ll be building an example category page and push the relevant product values into Google Analytics when it becomes visible. This will use the Google Tag Manager / data layer method.

The category page HTML structure is fairly simple. Each product has an ‘item’ class applied as well as the relevant data attributes such as ID, price, position and name. In a real world example each item would have the relevant details to display to the user such as image, name and link. In my test I simply added a CSS 'item' class to give each item a set space on the page.


<div class="products">

  <div class="item" productId="x123" productPrice="12.99" productPosition="1" productName="Example 1">



  <div class="item" productId="x245" productPrice="14.99" productPosition="2" productName="Example 2">



  <div class="item" productId="x784" productPrice="5.00" productPosition="3" productName="Example 3">




The JavaScript catches all products with a class of ‘item’ and binds a function to it whenever it becomes visible to the user. This function will gather the relevant product data attributes and push it into the data layer. Google Tag Manager can then pick on this and push it Google Analytics as an event with the additional product impression information.

When an item becomes visible we 'unobserve' it so that particular product does not send an impression event again. The 'threshold' is set to 1.0 which means 100% of the selected element needs to be visible before the function is called.

function onChange(entry) {

  entry.forEach((change) => {


    let productId ="productId");

    let productPrice ="productPrice");

    let productName ="productName");

    let productPosition ="productPosition");



      'event': 'productsImpression',

      'ecommerce': {

        'impressions': {

          'promotions': {

            'id': productId,

            'name': productName,

            'price': productPrice,

            'position': productPosition









let elements = document.querySelectorAll('.item');


let options = {

  threshold: [1.0]



let observer = new IntersectionObserver(onChange, options);


for (let elm of elements) {



Within Google Tag Manager a trigger will need setting up for event name ‘productsImpression’. You can see the reference to this event name in the JavaScript code above.

gtml trigger event example

Finally the Google Analytics event has been created which will fire when an event with name ‘productsImpression’ occurs. ‘Enable Enhanced Ecommerce Features’ and ‘Use data layer’ both need to be set to true. It would be recommended to change this event to a non-interaction hit as a product impression shouldn’t be classed as an interaction. Setting it as an interaction event would have a significant impact on reported bounce rate.

gtm tag example

If we put all this together and you use a Google Analytics debugging tool you should start to see events like this occurring per product impression. Pretty cool, right?

gtm analytic debug

Summary & considerations

  • Using this solution will improve the accuracy and reliability of product impressions and CTR within Google Analytics significantly.
  • This solution will fire a Google Analytics event per impression. Depending on your site this will inflate your event count so collection limits and quotas will need to be considered. An ideal solution would be to collect all impressions and then attach them to one Google Analytics event prior to a user leaving the page. The 'onbeforeunload' function might be used here.
  • I've adapted 'IntersectionObserver' for product impressions but it could be used for other aspects including promotions, ads or even contribute towards a content quality score.

Maximise business opportunity with data-driven decision making Contact us here.

About Matt:

Matt is an Analytics Solutions Architect at 26 with particular expertise within Google Tag Manager, CRO and all things technical such as HTML, CSS, JavaScript, Dojo, jQuery, PHP, Firebase, Angular & Ionic. He also enjoys building web / mobile apps outside of work.

Want to know more?

Let's connect