I’ve been recently looking for a solution to prevent certain scripts from firing unless the user starts interacting with the page. I initially planned to use the Scroll Depth trigger of Google Tag Manager (GTM), but found it to be unreliable. Why? Because this trigger does not actually check whether the user scrolls, but rather how much of the length of the page is in the viewport. In such cases, a short page can get to 100% Scroll Depth on the initial load if it fits in the viewport.
Why load scripts after the first user interaction
There are multiple reasons to prevent certain scripts from loading before the user clicks, scrolls or touches the screen. Many of them are related to performance.
Spiders and bots, such as Googlebot, do not interact with the pages they crawl. Thus, your website would not load certain scripts at all when being accessed by these crawlers. As a side-effect, your scores in performance checking tools, such as Google Pagespeed Insights, will also improve.
There are also performance-related benefits for users too. Preventing scripts from being loaded before the first scroll, click or touch, means the actual content on your website will load faster. The First Contentful Paint, which is also part of the Core Web Vitals should improve too.
How to load scripts on user interaction in Google Tag Manager
To accurately determine when the user actually starts scrolling, I’ve decided to use the addEventListener() method. If you’re not familiar with JavaScript, don’t worry. I will guide you step-by-step on how to fire scripts in GTM only after the user scrolls.
Create a custom HTML Tag
Copy & paste the following code snippet in your custom HTML tag in GTM.
<script>
['click', 'scroll', 'mousemove', 'touchstart'].forEach(function(e) {
window.addEventListener(e, firstInteraction, {
once: true
});
});
var userInteracted = false;
function firstInteraction() {
if (!userInteracted) {
userInteracted = true;
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'event': 'firstInteraction'
});
}
}
</script>
Code language: HTML, XML (xml)
Select the default trigger All Pages for this tag. It should look like in the following image.
This snippet tracks when the user actually starts interacting with your website, either by moving the mouse, clicking, scrolling or touching the screen. Unlike the Scroll Depth trigger of GTM, it does not take into consideration the length of the page and how much of is in the initial viewport.
Once it detects the first user interaction, it will execute a function which sends a custom event named firstInteraction
to the Data Layer. This is the custom event which we’ll later use as a trigger for scripts/tags we want to fire after the user interacts with the page.
The {once: true}
parameter makes sure that each event listener only runs once, so we’ll not be sending multiple custom events to the Data Layer other than the first interaction.
The userInteracted
variable is used to ensure the event is sent only on the first interaction. Otherwise, the event would be sent once for each type of event (click, scroll, mouse move, touch) .
Create a custom event trigger in GTM
Now that we send an event to the Data Layer after the first interaction, we need to use it as a trigger. Create a Custom Event trigger and set firstInteraction
as the event name. It should look like this:
Now you have a trigger which can be used to fire any tag in GTM after the user scrolls. I’ve set non-essential tags which were
Create tags using the new custom event trigger firstInteraction
I’ve set non-essentials tags to load only after the first scroll. This has greatly reduced the initial loading time of my web pages.
Here’s a screenshot of a HotJar Tracking Code tag firing when the firstInteraction
event is pushed in the DataLayer.
How to check if the scripts are loading on scroll
After you have created at least one tag using the firstInteraction
event as trigger, you can now use the Google Tag Assistant to confirm it loads after the user scrolls.
Open Preview Mode in Google Tag Manager
After you click the Preview button, the Tag Assistant will open in a new tab. Type the address of a web page on your website in the URL field.
I’m going to test the homepage, so it will look like the following image.
Click Start when you are done and a new tab will open with the URL of your website. You should see a confirmation that the Debugger is connected to this tab.
Check the Summary in the Tag Assistant
Before scrolling, the tags for which you’ve sent the firstInteraction
custom event as a trigger should not have fired. In addition, the event shouldn’t have been sent yet either.
In my example, I used the HotJar Tracking Code tag with this trigger, so it will look like this:
Scroll and check back the Tag Assistant
After you first scroll anywhere on your website in the tab connected to the debugger, you should see the custom event and the tags being fired.
If you’ve got similar results to the screenshot above, then your trigger is working as expected and you can submit the changes in Google Tag Manager.
Hello, Marius,
Very good and useful article!
Can you please be more specific on “I’ve set non-essentials tags to load only after the first scroll.”?
How to categorise tags in essential and non-essential?
Hi, Alin,
I would consider essential tags that should fire as early as possible (e.g. tracking conversions) and that have very little impact on performance (such as Google Analytics).
Non-essential are scripts that do not have a direct impact on revenue or conversion tracking, such as HotJar (I wouldn’t care if a session recording started a few seconds later), scripts that load pop-ups, etc.
Great post, used this for a client just now
Changing the trigger on the custom event to Window Loaded instead of Pageview will squeeze even a little more performance here as the data layer event won’t fire until at least the window loaded event has happened.
This way you’re getting the benefit of the not loading until AT LEAST the window loaded event has fired. With a page view trigger, in some scenarios where the user is navigating quickly through the site the first interaction happens early which means the GTM code could still trigger before the window loaded event so not the most optimal from a speed perspective
Thanks for this! it works great! I have tested it on a clients site just now, please keep these helpful tips coming