Scroll Tracking Recipe for GTM

September 27, 2017

Adds automatic scroll tracking to every page on your site and sends events to Google Analytics.

By default, tracks user scroll depth at the 10%, 25%, 50%, 75%, 90%, and 100% marks, but can be customized.

Ingredients

Tags

CU - Scroll Tracking - LunaMetrics Plugin

GA - Event - Scroll Tracking

Triggers

Event - Scroll Tracking

Variables

Debug Mode

DLV - attributes.distance

DLV - attributes.label

Instructions

1. Download Container File

Download the container JSON file.

(You may need to right-click on the link and choose “Save Link As” or “Save Target As” to save the JSON file to your computer.)

2. Import JSON File into GTM

Log into your own Google Tag Manager container and head to the Admin section of the site. Under Container options, select Import Container. Check out this blog post for more details about importing a container file.

3. Update With Your Own Tracking ID

Update or create a new Constant Variable named {{YOUR_GA_TRACKING_ID}} with your Google Analytics Tracking ID (a.k.a. UA Number).

4. Preview & Publish

Use the Preview options to test this container on your own site. Try testing each of the events to make sure they’re working properly. If everything looks good, go ahead and publish!

Optional: Update Scroll Breakpoints

You can customize how often events fire by editing the configuration at the end of the tag "CU – LunaMetrics Scroll Tracking Plugin."

Documentation

Scroll Tracking Library & Google Tag Manager Plugin

Plug-and-play dependency-free scroll tracker for observing user scroll behavior on the web. Supports everything north of IE8. Tracking waypoints can be set on:

  • Pixel depths
  • Percentages
  • Elements (via CSS selectors)

Tracking can be set to measure “every” occurrence (e.g., every 25%) or each of a list of occurrences (e.g., 10%, 25%, 90%). The area observed can be customized by setting a custom context. The library supports tracking nested scrollable areas (e.g., overflows).

Marker locations are refreshed when the document height changes or the window is resized.

Installation

Include the library in your code, then construct a ScrollTrackerNOTE: It’s up to you to ensure the DOM is ready before constructing your tracker. Register handlers for pixels, percentages, or elements by calling .on() and passing in a configuration object:

if (document.readyState !== 'loading') { 

  init();

} else {

  document.addEventListener('DOMContentLoaded', init);

}

function init() {

  var tracker = window.ScrollTracker();
  tracker.on({
    percentages: {
      every: [25]
    }
  }, function(evt) {

    console.log(evt.data.label); // > "25%"
    console.log(evt.data.depth); // > 500

  });

}

 

Additional handlers can be added at any time:

tracker.on({
  percentages: {
    every: [25]
  },
  elements: {
    each: ['.header', '.footer']
  }
}, someNewHandler);

Tracking With SPAs

To track scrolling with single-page applications (e.g. Angular apps), call ScrollTracker#reset() when a new "page" is rendered. This will reset the internal cache of marks that have been tracked. For example, using Angular 1.X.X & ngRoute:

// In your Config somewhere
$rootScope.$on('$routeChangeSuccess', function() {

  $scrollTracker.reset();

});

Google Analytics

To track scroll behavior with Google Analytics, replace YOUR_GA_PROPERTY_ID with your UA number and adjust the config variable to track what you’d like.

<script>
  (function(document, window) {

    var config = {
      percentages: {
        each: [10, 90],
        every: [25]
      }
    };
    var trackerId = YOUR_GA_PROPERTY_ID;  // e.g. UA-000000-00

    if (document.readyState !== 'loading') { 

      init();

    } else {

      document.addEventListener('DOMContentLoaded', init);

    }

    function init() {

      getTracker(trackerId, registerScrollTracker);

    }

    function registerScrollTracker(tracker) {

      var scrollTracker = window.ScrollTracker();
      scrollTracker.on(config, function(evt) {
        
        tracker.send('event', {
          eventCategory: 'Scroll Tracking',
          eventAction: evt.data.label,
          eventLabel: document.location.pathname,
          nonInteraction: true
        });

      });

    }

    function getTracker(trackerId, cb, ran) {

      var ga = window[window.GoogleAnalyticsObject] ;

      ga(function() {

        var trackers = ga.getAll();
        var len = trackers.length;
        var tracker;
        var i;

        for (i = 0; i < len; i++) {

          tracker = trackers[i];

          if (tracker.get('trackingId') === trackerId) return cb(tracker);
        
        }

        if (!ran) {
        
          setTimeout(function() {
            getTracker(trackerId, cb, true); 
          }, 0);

        }
      
      });
    
    }

  })(document, window);
</script>

Google Tag Manager Plugin

  1. Download the file ‘luna-scroll-tracking.json‘ from this repository.
  2. In Google Tag Manager, navigate to the Admin tab.
  3. Under the Container column, select Import Container.
  4. Click Choose Container File and select the ‘luna-scroll-tracking.json’ file you downloaded.
  5. Select Merge from the radio selector beneath the Choose Container File button.
  6. Select Rename from the radio selector that appears beneath the Merge selector.
  7. Click Continue, then Confirm.
  8. Navigate to the Tags interface – select the tag imported tag named GA Event – Scroll Tracking.
  9. Change the {{YOUR_GA_TRACKING_ID}} in the Tracking ID field to your Google Analytics Tracking ID (a.k.a. UA Number).

Once you publish your next container, scroll tracking will begin working immediately.

Technical Documentation

ScrollTracker(opts)

Constructs a ScrollTracker instance.

opts.context

HTMLElement to treat as scrolling context. Defaults to <body>.

var nestedTracker = ScrollTracker({
  context: document.getElementById('chat-sidebar')
});
opts.minHeight

Minimum height of context required to track. The tracker won’t run if the context height is less than the minHeight setting.

var nestedTracker = ScrollTracker({
  minHeight: viewportHeight()
});

function viewportHeight() {

  var elem = (document.compatMode === "CSS1Compat") ?
    document.documentElement :
    document.body;

  return elem.clientHeight;

}
ScrollTracker#on(config, handler)

Registers a handler for a given configuration.

config.percentages.every

Array of numbers. Track every n percentages from 0 to 100 for each number in the array.

tracker.on({
  percentages: {
    every: [25]  // Tracks 25%, 50%, 75%, and 100%
  }
}, handler);
config.percentages.each

Array of numbers. Track each percentage in the array.

tracker.on({
  percentages: {
    each: [10, 90]  // Tracks 10% and 90%
  }
}, handler);
config.pixels.every

Array of numbers. Track every n pixel depths from 0 to the document height for each number in the array.

tracker.on({
  pixels: {
    every: [100]  // Tracks 100px, 200px, 300px, ...
  }
}, handler);
config.pixels.each

Array of numbers. Track each pixel depth in the array.

tracker.on({
  pixels: {
    each: [100, 900]  // Tracks 100px and 900px
  }
}, handler);
config.elements.every

Array of CSS selectors. Track when each instance of a matched element scrolls into view.

tracker.on({
  elements: {
    every: ['.li .widget']  // Tracks .li .widget[0], .li .widget[1], ...
  }
}, handler);
config.elements.each

Array of CSS selectors. Track first element that matches each selector in the array.

tracker.on({
  elements: {
    each: ['.widgets', '.footer']  // Tracks '.widgets', '.footer'
  }
}, handler);
ScrollTracker#destroy()

Cleans up timer and event bindings.

ScrollTracker#reset()

Resets the internal cache of tracker marks.