Scroll Tracking Implementation in Google Tag Manager V2 24


Scroll tracking implementation is made super easy with Google Tag Manager Version 2. Implement scroll tracking in your website if you are interested to gather more information about your visitors behavior. Scroll tracking is one way to measure the way or how much of your posts have been read and consumed.

Scroll tracking technique collects valuable information about the percentages of 00%, 25%, 50%, 75%, and 100%, Pixel Depth and Timing as your readers scroll down the page. Scroll tracking report entails powerful events that took place within your website pages. So why you don’t take advantage of it?

In this post, I will be demonstrating step by step how to implement scroll tracking for your target page(s) using Google Tag Manager V2. You might think implementing scroll tracking via Google Tag Manager confusing. But if you follow the following major steps described in this article, you will find tracking scroll depth easy and worthy.

Let’s get started..

 

Scroll Tracking Implementation: First Steps

What you need to have first?

First things first, the best course of action is to have some knowledge of how Google Tag Manager –or any Tag Management System— is working. Holding a concept of its terminology (e.g Tags, Triggers, and Variables) and how GTM works will help and make your implementation so simple .

Second thing you need to is having Google Tag Manager container already installed in your website pages with Google Analytics.

Third thing: to start implementing scroll tracking using Google Tag Manager V2, you need to have jQuery Scroll Depth. You can find the script below. This piece of snippet is developed by Rob Flaherty. So many credits to Rob for that.

<script>

/*!
 * @preserve
 * jquery.scrolldepth.js | v0.7.1
 * Copyright (c) 2014 Rob Flaherty (@robflaherty)
 * Licensed under the MIT and GPL licenses.
 */
;(function ( $, window, document, undefined ) {

 "use strict";

 var defaults = {
 minHeight: 0,
 elements: [],
 percentage: true,
 userTiming: true,
 pixelDepth: true,
 nonInteraction: true
 };

 var $window = $(window),
 cache = [],
 lastPixelDepth = 0,
 universalGA,
 classicGA,
 standardEventHandler;

 /*
 * Plugin
 */

 $.scrollDepth = function(options) {

 var startTime = +new Date;

 options = $.extend({}, defaults, options);

 // Return early if document height is too small
 if ( $(document).height() < options.minHeight ) {
 return;
 }

 /*
 * Determine which version of GA is being used
 * "ga", "_gaq", and "dataLayer" are the possible globals
 */

 if (typeof ga === "function") {
 universalGA = true;
 }

 if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
 classicGA = true;
 }

 if (typeof options.eventHandler === "function") {
 standardEventHandler = options.eventHandler;
 } else if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") {
 standardEventHandler = dataLayer.push;
 }

 if (options.percentage) {
 // Establish baseline (0% scroll)
 sendBaseline('Percentage');
 } else if (options.elements) {
 sendBaseline('Elements');
 }

 /*
 * Functions
 */

 /*
 * Putting this in a separate function because the Baseline event may soon be removed entirely
 */
 function sendBaseline(action, label) {

 if (standardEventHandler) {

 standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': 'Baseline', 'eventValue': 1, 'eventNonInteraction': true });

 } else {

 if (universalGA) {

 ga('send', 'event', 'Scroll Depth', action, 'Baseline', 1, {'nonInteraction': true });

 }

 if (classicGA) {

 _gaq.push(['_trackEvent', 'Scroll Depth', action, 'Baseline', 1, true]);

 }

 }

 }

 function sendEvent(action, label, scrollDistance, timing) {

 if (standardEventHandler) {

 standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});

 if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
 lastPixelDepth = scrollDistance;
 standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': 'Pixel Depth', 'eventLabel': rounded(scrollDistance), 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});
 }

 if (options.userTiming && arguments.length > 3) {
 standardEventHandler({'event': 'ScrollTiming', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventTiming': timing});
 }

 } else {

 if (universalGA) {

 ga('send', 'event', 'Scroll Depth', action, label, 1, {'nonInteraction': options.nonInteraction});

 if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
 lastPixelDepth = scrollDistance;
 ga('send', 'event', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, {'nonInteraction': options.nonInteraction});
 }

 if (options.userTiming && arguments.length > 3) {
 ga('send', 'timing', 'Scroll Depth', action, timing, label);
 }

 }

 if (classicGA) {

 _gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, options.nonInteraction]);

 if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
 lastPixelDepth = scrollDistance;
 _gaq.push(['_trackEvent', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, options.nonInteraction]);
 }

 if (options.userTiming && arguments.length > 3) {
 _gaq.push(['_trackTiming', 'Scroll Depth', action, timing, label, 100]);
 }

 }

 }

 }

 function calculateMarks(docHeight) {
 return {
 '25%' : parseInt(docHeight * 0.25, 10),
 '50%' : parseInt(docHeight * 0.50, 10),
 '75%' : parseInt(docHeight * 0.75, 10),
 // 1px cushion to trigger 100% event in iOS
 '100%': docHeight - 5
 };
 }

 function checkMarks(marks, scrollDistance, timing) {
 // Check each active mark
 $.each(marks, function(key, val) {
 if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
 sendEvent('Percentage', key, scrollDistance, timing);
 cache.push(key);
 }
 });
 }

 function checkElements(elements, scrollDistance, timing) {
 $.each(elements, function(index, elem) {
 if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
 if ( scrollDistance >= $(elem).offset().top ) {
 sendEvent('Elements', elem, scrollDistance, timing);
 cache.push(elem);
 }
 }
 });
 }

 function rounded(scrollDistance) {
 // Returns String
 return (Math.floor(scrollDistance/250) * 250).toString();
 }

 /*
 * Throttle function borrowed from:
 * Underscore.js 1.5.2
 * http://underscorejs.org
 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 * Underscore may be freely distributed under the MIT license.
 */

 function throttle(func, wait) {
 var context, args, result;
 var timeout = null;
 var previous = 0;
 var later = function() {
 previous = new Date;
 timeout = null;
 result = func.apply(context, args);
 };
 return function() {
 var now = new Date;
 if (!previous) previous = now;
 var remaining = wait - (now - previous);
 context = this;
 args = arguments;
 if (remaining <= 0) {
 clearTimeout(timeout);
 timeout = null;
 previous = now;
 result = func.apply(context, args);
 } else if (!timeout) {
 timeout = setTimeout(later, remaining);
 }
 return result;
 };
 }

 /*
 * Scroll Event
 */

 $window.on('scroll.scrollDepth', throttle(function() {
 /*
 * We calculate document and window height on each scroll event to
 * account for dynamic DOM changes.
 */

 var docHeight = $(document).height(),
 winHeight = window.innerHeight ? window.innerHeight : $window.height(),
 scrollDistance = $window.scrollTop() + winHeight,

 // Recalculate percentage marks
 marks = calculateMarks(docHeight),

 // Timing
 timing = +new Date - startTime;

 // If all marks already hit, unbind scroll event
 if (cache.length >= 4 + options.elements.length) {
 $window.off('scroll.scrollDepth');
 return;
 }

 // Check specified DOM elements
 if (options.elements) {
 checkElements(options.elements, scrollDistance, timing);
 }

 // Check standard marks
 if (options.percentage) {
 checkMarks(marks, scrollDistance, timing);
 }
 }, 500));

 };

})( jQuery, window, document );
jQuery.scrollDepth();

</script>

Please note I wrapped the code with <script> jQuery Scroll Depth </script>. Also I added before </script> this:  jQuery.scrollDepth(); . If you want to have a look on the scroll tracking code in its origin, you can visit the source from this link  or GitHub.

Tip: Please give some time to read what s written within the script above. For sure, it will give you some insights about data being collected, which analytics library can be used with (e.g GA Classic, GA Universal) ,devices and more .

 

Scroll Tracking Implementation: Second Steps

Scroll Tracking via Google Tag Manager Version 2:

Now, it is the time to start implementing the above scroll tracking code into your Google Tag Manager V2. Now, go ahead to https://tagmanager.google.com and enter you Google log in credentials.  By now, I am guessing you already had your GTM Container snippet ready and it is installed with Google Analytics in your website. If so, you are doing fine so far.

Next, in this time you need to create a new Tag on Google Tag Manager V2. Choose CUSTOM HTML TAG. This tag will hold our Scroll Depth code above. So copy and past the code into Custom HTML Tag. Save this tag for the time being as it is. We will come back to configure it more when we finish creating Triggers.

Note, you can choose any descriptive name for your custom tag.

Setting up Triggers:

Next, we need to create a Trigger for our Customer HTML Tag to fire. So, go and click on Triggers. Start by press “New”. Give your Trigger a name. In Choose Event, click on Custom Event. Then continue.

We are going to create a Firing rule for this Trigger.

Event Name : ScrollDistance

Event contains  ScrollDistance.

Save your Trigger

Remember we did not finish before our Tag in Custom HTML Tag. It is because we just created for it a Trigger .And the latter is ready to be connected to Custom HTML Tag.

So, go back and click on Tags, pick up the the Tag that you created before. We are going to fire Custom HTML Tag with Some Pages. Now it is easy, you should choose Trigger that you created before with : Variable: Page Path. Operation: contains. Value is your website URL. Then Save Tag.

Setting Variables:

In Google Tag Manager, this is a rule: Every Tag needs Trigger. And every Trigger needs Variables to fire on.

To start with setting variable for your scroll tracking, you need to create three Data Layer Variable. So click “New”. Then choose Data Layer Variable with these settings:

Data Layer Name : eventCategory

Data Layer Version : 2

Save Variable. See the screenshot

scroll tracking in google tag manager

Create second one as follow:

Data Layer Name : eventAction

Data Layer Version : 2

Save Variable.

Create third one as follow:

Data Layer Name : eventLabel

Data Layer Version : 2

Save Variable.

Now you are done with setting up the necessary Variables.

Google Analytics Event Scrolling:

After creating your Customer HTML Tag with corresponding Triggers. Now you will need to create Google Analytics Event Tracking. So Choose Google Analytics as your product. Pick up your Tag Type. Next configure your Tag as follow:

scroll tracking in google analytics

Tracking Id: Google Analytics

Track type: Event. (not page-view)

Category: {{Page Path}} or {{eventCategory}}.  (I chose Page Path as a category as I have to identify which page the page depth triggered.)

Action: {{eventAction}}

Label: {{eventLabel}}

Et voila, now you are almost done.

Scroll Tracking Debugging :

Debugging and checking for problems with Google Tag Manager made easy, please go up on your right hand and click on Preview and Debug.

Google tag manager debuger

This is to verify your scrolling configuration before publishing. Open your website in a new Tab. You can have access to a very valuable information about what you implemented and more. Don’t forget to create a Version then Publish your Scroll tracking on Google Tag Manager when you finish debugging.

Summary:

Google Tag Manager version 2 comes in with too much simplicity compared with GTM V1. It helps a lot in simplifying scroll depth tracking so much. Now, it is possible to start enjoying reports of implementing scroll tracking in your website via GTM by visiting your Google Analytics account. You can see those kind of events live as they occur by clicking Real Time > Events or you can wait for almost 48 hours to appear under Behavior > Events in Google Analytics Reports.

 

What do you think about scroll tracking implementation? How did you experience it? Share please your thoughts , comments, feedback in the comment block below. If you find this post useful, please do share it, be social! Don’t forget to subscribe to our newsletters, it is your chance to receive marketing tips, updates and more for free. 🙂


About Omar Belkadi

Omar Belkadi is a Search Engine Marketing Expert who specializes in Analytics, SEO and PPC advertisement. Omar has been experiencing for long in the field of digital marketing which backed up with related experience and certifications.


Leave a comment

Your email address will not be published. Required fields are marked *

24 thoughts on “Scroll Tracking Implementation in Google Tag Manager V2

  • Richard

    Great article!

    There is only one thing, which I would like to know more: how to disable baseline. Is it as simple as putting comment to this lines of code:
    // Establish baseline (0% scroll)
    // sendBaseline(‘Percentage’);
    //} else if (options.elements) {
    // sendBaseline(‘Elements’);
    //ga(‘send’, ‘event’, ‘Scroll Depth’, action, ‘Baseline’, 1, {‘nonInteraction’: true });
    //_gaq.push([‘_trackEvent’, ‘Scroll Depth’, action, ‘Baseline’, 1, true]);

    ?

    It would be great not having base line, and then turn event non-interaction parameter to false. It would help with measuring real time on-screen.

    Thanks for information if comenting those lines will work. It looks like working but I don’t want to mess with data :).

    Kind regards,
    Richard

    • Omar Belkadi Post author

      Richard, thank you for commenting and sharing your issue.

      What I understood from you is that you wanted to Turn off the Percentage tracking on your script? if so, you can do that through turning off the scroll percentage. What you need to do is simply set the value to FALSE. Your default setting is set to TRUE. For example:

      percentage: false,
      userTiming: false,
      pixelDepth: false,
      nonInteraction: false
      });

      Above, all variables are turned off, therefore nothing will be sent to Google Analytics. Note nonInteraction can be adjusted too via Google Tag Manager Settings. Try the mentioned solution and let me know if it works with you? That can help others with the same.

      Hope I did answer your question.
      Regards,
      Omar

      • Richard

        Omar, thank you very much for your answer! Maybe I was a little bit unclear in my first comment. I would like to disable “baseline” event from firing :).

        After that I would turn all scroll events to interaction ones, and Analytics will measuer more appropriate time on page :).

        When there is baseline hit, I don’t want to make all those scroll events to interactive ones, because “baseline” hit will make bounce rate not appropriate (too low).

        Kind regards,
        Richard

  • Danny

    i used this script and found it a bit annoying to show the pixel depth for a client. I created a blocking rule in gtm so that it would not fire if the categoryAction was equal to pixel depth. Thank you so much for the great tutorial and much thank you for delivering the script to us.

    • Omar Belkadi Post author

      Hello Danny,

      Most welcome. Glad to read from you and Thank you for feedback. I tried to read something from your interesting blog (mawni.dk),but I found all content in Danish Language .

      Regards,
      Omar

  • Van

    Thank you so much for your detail post!
    There is one thing I would like to ask for your clarification as below
    “…..to start implementing scroll tracking using Google Tag Manager V2, you need to have jQuery Scroll Depth. You can find the script below….”
    => Do I need to install JQuerry on my website or before proceed to further steps in your post, or no need to do it?

    Thanks & Regards

    Van Nguyen

    • Omar Belkadi Post author

      Hi Van,

      Very good question indeed! Thank you for highlighting this point. When I implemented the scroll tracking on my website, I used to have JQuery on my website. If you inspect your website or you perform a view page source (ctrl+u), you will see the Jquery like this:
      …….wp-includes/js/jquery/jquery.js?ver=1.11.2’>.

      Note I am using WordPress CMS. Most modern CMS platform are already having JQuery installed.

      In brief, I do believe you need to have JQuery plugged in to successfully track scroll tracking!

      What is your Content Management System?

      Regards,
      Omar

      • Van

        Thank you for your quick reply,

        As I guess as well, we do need to install Jquerry before implement scroll tracking, thanks for your confirmation.

        Our CMS is develop by our own framework, that why I need to make clear 🙂

        Regards,

        Van Nguyen

          • Van

            It worked successfuly, but there is some further thing I would like to ask for your experiece with comment.

            Follow your guide: “……{{Page Path}} or {{eventCategory}}. (I chose Page Path as a category as I have to identify which page the page depth triggered.)….”

            As far as I know, event will be record with any page it fire on current. Beside that, we can use page path level in GA to identify which page and page path, so I don’t understand why we use {{Page Path}} variable. It also make Event Category more complex when track with other type of Event in addition.

            Please correct me if my thinking is wrong 🙂

            Thanks & Regards

            Van

          • Omar Belkadi Post author

            Hi Van,

            Thank you for your inquiry.

            Google Tag Manager comes in to simply tagging and collecting data. You can make sense of your data by selecting what makes you pull out the right or needed data.
            I can say you that you are free to populate the fields according to your needs. For example, you can choose for Label: {{Referrer}} or something different..etc

            You are free to select the way you collect data through GTM.

            Hope it helps,
            Regards

  • Nicolas Colombres

    Hello,

    I just started with GTM. This article is a bit challeging but I will try to implement this and let you know how it went! Thanks for this 😀

    • Omar Belkadi Post author

      Hey Nicolas,

      Thank you for your comment.Hope Australia is not very hot now!
      Well, I do encourage you to try it. It worths a trial. If you need any help please get back to me.
      I am looking to hear from you How it will go with you regarding the scroll implementation?
      By the way, what is CMS of your website?

      Happy scrolling,
      Best,
      Omar

  • Paula

    Hi omar! thank you for this perfect tutorial! i wanted to ask you a question about the last part of it:

    After creating the tag “Google Analytics Event Scrolling” (the last one). Should i connect the trigger made before to this tag too? I’m not publishing yet because i want to understand this last part. Hope you can answer me shortly.

    Thanks again for the tutorial!

    Paula,
    beautipul24.blogspot.com

    • Omar Belkadi Post author

      Hi Paula,

      Thank you for question and I am sorry if I am little late to reply to your question. As you know it is now holiday season. I hope you solved the problem since then!

      Please bear in mind a principle In Google Tag Manager, this is a rule: Every Tag needs Trigger. And every Trigger needs Variables to fire on. Yes, you should connect triggers with tags as described here! If you did not succeed, you try again and again. For sure you will find your way.

      Hope you find it easy,
      Happy Tagging, Paula,

      Best of regards,
      Omar

  • Lore

    Hi Omar,
    We have used your instructions to set up percentage scroll tracking in our website.
    All works fine.
    The only issue I have, is that the bounce rate is heavily influenced by the script, although we have set all ‘non-interaction hi’ to ‘True’ in our Event Tags in Analytics, and we changed
    It looks like the script itself is sending an interaction to Google Analytics directly. Can you confirm?

    What would your solution be? We would like to measure scroll depth as an interaction from 25% onwards only.

    This is what we use:

    /*!
    * @preserve
    * jquery.scrolldepth.js | v0.7.1
    * Copyright (c) 2014 Rob Flaherty (@robflaherty)
    * Licensed under the MIT and GPL licenses.
    */
    ;(function ( $, window, document, undefined )
    {
    “use strict”;

    var defaults = {
    minHeight: 0,
    elements: [],
    percentage: true,
    userTiming: true,
    pixelDepth: true,
    nonInteraction: true
    };

    var $window = $(window),
    cache = [],
    lastPixelDepth = 0,
    standardEventHandler;

    /*
    * Plugin
    */
    $.scrollDepth = function(options) {
    var startTime = +new Date;

    options = $.extend({}, defaults, options);

    // Return early if document height is too small
    if ( $(document).height() 2 && scrollDistance > lastPixelDepth) {
    lastPixelDepth = scrollDistance;
    standardEventHandler({
    ‘event’: ‘ScrollDistance’,
    ‘eventCategory’: ‘Scroll Depth’,
    ‘eventAction’: ‘Pixel Depth’,
    ‘eventLabel’: rounded(scrollDistance),
    ‘eventValue’: 1,
    ‘eventNonInteraction’: true
    });
    }

    if (options.userTiming && arguments.length > 3) {
    standardEventHandler({
    ‘event’: ‘ScrollTiming’,
    ‘eventCategory’: ‘Scroll Depth’,
    ‘eventAction’: action,
    ‘eventLabel’: label,
    ‘eventTiming’: timing
    });
    }
    } else {
    ga(‘send’, ‘event’, ‘Scroll Depth’, action, label, 1, true);

    if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
    lastPixelDepth = scrollDistance;

    ga(‘send’, ‘event’, ‘Scroll Depth’, ‘Pixel Depth’, rounded(scrollDistance), 1, true);
    }

    if (options.userTiming && arguments.length > 3) {
    ga(‘send’, ‘timing’, ‘Scroll Depth’, action, timing, label, true);
    }
    }
    }

    function calculateMarks(docHeight) {
    return {
    ‘25%’ : parseInt(docHeight * 0.25, 10),
    ‘50%’ : parseInt(docHeight * 0.50, 10),
    ‘75%’ : parseInt(docHeight * 0.75, 10),
    // 1px cushion to trigger 100% event in iOS
    ‘100%’: docHeight – 5
    };
    }

    function checkMarks(marks, scrollDistance, timing) {
    // Check each active mark
    $.each(marks, function(key, val) {
    if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
    sendEvent(‘Percentage’, key, scrollDistance, timing);
    cache.push(key);
    }
    });
    }

    function checkElements(elements, scrollDistance, timing) {
    $.each(elements, function(index, elem) {
    if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
    if ( scrollDistance >= $(elem).offset().top ) {
    sendEvent(‘Elements’, elem, scrollDistance, timing);
    cache.push(elem);
    }
    }
    });
    }

    function rounded(scrollDistance) {
    // Returns String
    return (Math.floor(scrollDistance/250) * 250).toString();
    }

    /*
    * Throttle function borrowed from:
    * Underscore.js 1.5.2
    * http://underscorejs.org
    * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
    * Underscore may be freely distributed under the MIT license.
    */
    function throttle(func, wait) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    var later = function() {
    previous = new Date;
    timeout = null;
    result = func.apply(context, args);
    };
    return function() {
    var now = new Date;
    if (!previous) previous = now;
    var remaining = wait – (now – previous);
    context = this;
    args = arguments;
    if (remaining = 4 + options.elements.length) {
    $window.off(‘scroll.scrollDepth’);
    return;
    }

    // Check specified DOM elements
    if (options.elements) {
    checkElements(options.elements, scrollDistance, timing);
    }

    // Check standard marks
    if (options.percentage) {
    checkMarks(marks, scrollDistance, timing);
    }
    }, 500));
    };
    })( jQuery, window, document );

    jQuery.scrollDepth();

    • Omar Belkadi Post author

      Hi Lore,
      How are you doing? Thank you for writing to us.
      I have reports from GA that all is under control with us here.
      However, I would suggest you to go GTM Google+ Community.
      Hope this can help you.
      Best.

  • Lore

    Hi Omar,
    We have used your instructions to set up percentage scroll tracking in our website.
    All works fine.
    The only issue I have, is that the bounce rate is heavily influenced by the script, although we have set all ‘non-interaction hi’ to ‘True’ in our Event Tags in Analytics, and we changed
    It looks like the script itself is sending an interaction to Google Analytics directly. Can you confirm?

    What would your solution be? We would like to measure scroll depth as an interaction from 25% onwards only.

    I wish I could send you the code we use in a sort of attachement: we basically replaced every Event Noninteraction in ‘True’ and still this script is sending interactions in Analytics

    • Omar Belkadi Post author

      Hi Lore,
      Thank you for writing to us.
      I read your comments. In my side all is good! I don t know how you got inflation of hits. I would suggest to go Google Tag Manager Google+ community. I am sure you can have more opinions one that!
      I hope it helps.
      Best,
      Omar

  • Pingback: Dan Nicholson

  • BN

    Do you have any examples of targeting when a specific ID or Class scrolls into view? My page has very clearly defined sections, and instead of showing percentage, it would be much better for reporting to show which sections people scrolled to. I know this is possible in the element: [], line, but not sure how to correctly target both ID’s and Class’s is it just “div.section-1”, “div.section2” ??

    • Omar Belkadi Post author

      Hi Dan,
      Thank you for showing up as well as commenting. I am sorry, Dan, I don t have examples for the time being!
      Hopefully, I can find time to do that in a next post.

  • Michael

    Thanks for this interesting post.

    How does the timing work?

    We can see scroll distance in the Events report, but I can’t seem to figure out how to review the timing feature in GA reports.

    What do you recommend?