How to #measure SEO Dwell Time with Google Analytics and Google Tag Manager

By | August 23, 2019

In this video, I’m going to show you how you
can measure dwell time with the help of Google Analytics and Google Tag Manager. That will tell you how much time they user
spend on your landing pages before he returned back to the search engine result pages and
in turn help you to optimize your landing pages for better search rankings. All and more, coming up. Hey there, welcome back to another video of teaching you the data-driven way of digital marketing. My name is Julian. And today we want to talk about how you can
measure dwell time with the help of Google Analytics and Google Tag Manager. Now, what does dwell time really all about? It’s when you as a user, click on a result
in a search engine, then go to that landing page and spend some time there and maybe,
then click on the back button to return to the search engine result pages. The time that you spend on the landing page
before going back to the search engine result page is called dwell time. And this is a bit disputed, but Google might
use that time because they can actually measure the click out and then coming back to the
search result page as a ranking factor. Why would they use the dwell time as a ranking
factor? Well, if a user spends only seconds on a landing
page, and then goes back to the search engine result page to click on another result, then
he might have had a bad experience. And that might be an indication that the result
is not as relevant to the search term that the user has actually entered. Now, don’t get me wrong. This is one of many factors that Google takes
into consideration like links, Page Speed, the content that is on the website obviously
and dwell time is just a tiny fraction of that probably. But if you want to pay close attention to
all these different ranking factors, then you also want to take a look at the dwell
time. Now Google doesn’t actually give us this data,
so we would need to measure it ourselves. And there is a genius technique by Simo Ahava. He has written a blog post about the SERP
bounce time, which is the dwell time that he figured out how to measure with the help
of Google Tag Manager and Google Analytics. Really a genius method of combining the powers
of JavaScript, Google Tag Manager, Google Analytics and the browser history API together
into a tracking deployment it will give us the dwell time. If you want to find out more about this technique,
I’ll also going to link up his blog post down below. But today, I want to give you a tutorial on
how to implement this with the help of Google Tag Manager. Now, we got lots to cover. So let’s dive in. All right, let’s start out with a demo on
what our implementation will look like, and what data we can get. So I have this implemented on measureschool. So I’m gonna look for measureschool on Google. And I’m going to click on one of the results
and the page loads like normally. The only thing that the user can notice is
that there is a #GREF appended to the URL when he comes from Google. Now, the interaction that we want to track
is whether the user goes back to the search engine result pages after he has landed on
our page. So on this first page, if I click on the spec
button, again, nothing really happens for the user. But there’s actually tracking firing in the
background, we can detect whether the user clicked on this back button, or went back
in the browser and send a timing head over to Google Analytics. What will this look like in the end? In Google Analytics, I’ve built a custom report
here that will give me the page URL and the actual average user timing. So everybody who went back to the search engine
result pages will send back a timing hit telling Google Analytics the seconds that he will
on the page. And if he ever searches out, you will see
that on this page, for example, people stayed 305 seconds, which is already pretty long,
probably started watching the video. And then they got the information that they
wanted and return back to Google. But there are pages here that are way shorter
so he only three seconds, probably a user clicked on the result. And notice that’s not for him, or so complicated
to set up. And we’re back and look for another result. So maybe there’s something we can do on this
page to optimize it to have the user stick around longer, or given more options to continuous
journey on our page. So really great data when it comes to optimizing
your pages, but also specifically tracking for the people coming from Google and extend
that time in terms of going back to the search engine result page. Now, the magic that we have implemented here
comes really from a pending the hash bang and then detecting when the user tries to
go back to the search engine result page. In between, there’s actually a step that detects
that and sends over the time and hit to Google Analytics. Everything not really visible to the user
itself but definitely to Google Analytics and our tracking. So let’s see how we can set this up with Google
Tag Manager. So here’s my Google Tag Manager account. I already have Google Tag Manager installed
on this demo shop here. And I have a Google Analytics page view tag
firing so we can have a base installation of Google Analytics already set up. Now the first step is copying the custom HTML
tag from Simo’s site. So we have here the whole HTML tag that you
can simply copy. And in our Google Tag Manager account will
implement this by a custom HTML tag. Go over to tags, click on new. And then as the tag configuration, we’ll
choose our custom HTML. And here we’re going to implement the custom
HTML. Now let’s give this all a name. This is a listener for our SERP Bounce and
take a closer look at the code right here. Now, the code is really divided in two parts
here. One is the part that actually detects whether
you come from Google and then adds the #GRef to your URL, it’s this part. And then the second part would be to actually
detect when the user does the action of the back and then calculate the time and then
fire our Google Analytics tag. And finally, redirect the user back to the
search result page. Since these are two functionalities, let’s
comment one of those out just to take this step by step. And attach in all pages trigger to this whole
thing. I’m also going to add a line of code, which
you don’t have to do, just to show us what is happening here. So here we have a line of an alert code that
will just stop the browser. You shouldn’t do this in production, just
for testing and showing and doing this right now. Let’s refresh and go back to our demo shop,
reload the page and our listener for the SERP Bounce is firing. That’s a good time. But nothing is happening in the browser. And this is totally normal because we actually
didn’t come from Google at this point. So let’s try to simulate this. You just go to Google and put in So here we go. So this site doesn’t really exist. So you’ll see some weird stuff here. It’s running on my local machine. Nonetheless, it will work if I click on this
first result. We’re coming from Google to our page, we get
this message that a Google referral was detected. And now our script will add the #GREF. Let’s click okay here and we see in the
URL the #GREF has been added to the URL. Now what happens or what should happen when
I click on the back button because I want to get back to the SERPs? We just are removing that #GREF. This is very useful because, in the time of
detecting the #GREF being changed, in essence, changing the history state, we have another
signal to send from the browser to Google Tag Manager saying that the user wants to
go back to the SERPs, please calculate a time that he was on the page. And we can do this with a nifty trick here. And finally, just invoke the history change,
so programmatically send the user back where he was previously on that previous page. And that’s part of the second part of the
script that we have commented out. So let’s take a look at that. Let’s get rid of our comments here and take
a look. So first of all, if a history change is detected,
and we need to have a special trigger for this, which we’re going to set up in a second,
then simply look at the old history fragments. So this GREF? If yes, then calculate the time. And as you see here, we’re actually making
use of a data layer variable, which we need to generate in a second, in this data layer
variable just looks at when GTM started and deducts this from the actual time that we
have right now. And therefore getting the milliseconds that
we were on the page itself that is all passed into the data layer. And as a special event called Return to SERP,
that then transfers the time that we calculated up here and has a special function called
Event Callback. Now, this Event Callback is a special function
within Google Tag Manager data layer, where you can enter a function just like him, and
it will be invoked once Google Tag Manager has fired all the tags that are related to
the Return to SERP event. That is very crucial because, in the short
period of time of the user clicking on the event and being redirected back to his old
page, we want to fire our Google Analytics tag with the time information. Now, after this is all done, this is invoked
the window history go minus one, which simply says that the browser should go back one step. Let me add another line of code here. All right, this should just stop the browser
again, and give us an alert message. Again, you shouldn’t do this in production. And now we can go ahead and try this out before
we need to actually build a special trigger that listens to this history change event. And Google Tag Manager has a built-in trigger
for this. So we can just add another trigger to this
tag, create a new trigger, and will utilize the built-in history change listener. So here, we can go to history change. And we only want to fire this on certain events. One is the History Source should equal popstate. This simply says, if any kind of change is
happening in the History API, which is basically these two buttons here, then fire this and
the new history fragment. So the step that we are going to should be
blank, which means we could put in a regex that matches that with the caret and the dollar
sign. By the way, if you don’t have the history
source and the new history fragment available, you would need to activate them in the built-in
variables. Let’s save this for now. This is a history event back to SERP. Let’s save this, and it has been attached
to our tag. Now, these are two triggers that either fire
on all pages, this is every time a new page loads. Remember, it will only actually go through
the execution order here once we detect that the user comes from Google. Or if there is a history fragment, a GREF
available in the URL only, then it will actually do any kind of calculations. So there are really a lot of rules already
built into the script. And we need to fire them on all pages because
we want to detect whether the user comes from Google. And then again, if the user clicked on the
back button. Now, let’s save this. Before we try this out, let’s click on the
refresh button. We have an error here, 3869, let’s take a
look. Probably my alert statement. Yep, I forgot the quotation marks that should
do it. Let’s try this out again. And we also need to build a data layer variable
that’s named GTM start. So I’m just going to copy the exact name here
because that’s a tag. Go over to variables, and utilize the built-in
capabilities of pulling out data from the data layer by a data layer variable. And we want to get the GTM start value. Name this correctly. And by the way, this is a default value that
we can see on any page. If you go to the page view here and look into
our data layer, we see that as a GTM start page, which really just tells the time when
Google Tag Manager was deployed, and this event is fired in the page view. This is happening by default, we are just
pulling it out of the data layer. All right, now that we have that setup. Let’s try it out. Again, I’m going to go to Google, click on
the event, click on the search result, we get that there’s a Google referral detected
and the GREF will be added. Here we go. Our tags fire like normally. And if the user now wants to return to return
to the SERPs, he clicks on the back button. And we get our message here, which is built
in we are returning to the SERPs. So this was detected. Now the time was calculated which 21,957 milliseconds
about 21 seconds. And afterward, once I click on OK here, we
will be redirected back to our previous page, which in our case, is Google. So from that state, everything works just
fine. Now the only thing that we need to do is actually
send data to Google Analytics. First of all, let’s get rid of our alert statements
here because I don’t want to have this in production. We now know how it works and we can set up
our Google Analytics tag. Now this Google Analytics tag will purely
base on this data layer push. So we should look at this data layer push
a little bit closer. There’s an event called Return to SERP which
will trigger our Google Analytics tag on. There is a data layer variable called time
to SERP which we need to create in order to get the time. And that’s basically already it. So let’s start out by building our data layer
variable for the time to SERP. Go over to variables, and simply build a new
data layer variable. Put in our key, which we have pushed into
the data layer, that should pull it out. Now, we can use this variable in our trigger,
we just build a custom event trigger, we should call Back to SERP. And configure it with our custom event, which
we pushed into the data layer, which was return SERP. Before we save this, we can put in a filter
to only fire this in certain circumstances. It is something that Simo has in his trigger
as well to actually say, if the time to SERP is longer than the session time, mostly 20
minutes or 30 minutes. By default, it’s 20 minutes I believe. We can put in a number here. Like if the user returns after half an hour,
don’t fire this. So only if this is less than the half an hour,
we should fire this. This is actually one zero too much. So that should do it. Only if the user is shorter than half an hour
on the page and goes back to the SERP, we want to fire our tag. Let’s save this. And now our triggers set up. Only what’s left to do is to build a Google
Analytics tag for our timing event, which will fire on back to SERP. Let’s choose our Google Analytics tag here
Universal Analytics. And the track type will be in this time timing. And timing is something that is not often
used. But if we are sending milliseconds over to
Google Analytics, Google Analytics has actually a protocol to interpret this time and build
this into the data system that they have available. You might have seen this in page timing, for
example, when you see how long a page loads in Google Analytics. These are calculated with this timing event. So we will utilize this here. And as the variables category and value, we
can fill out whatever we want. It’s not often used in the end, it’s like
the event categories that you have. What’s just important is that you could say,
how do you want to divide it by the variable should be the parameter in the end that you
want to set over. And then the value should be the time that
you’re sending over. So here, we can already fill out the value,
which is in our case; the time to SERP, and then the variable by what do we want to view
this data. In our case, that would be by page URL, or
by page path. Let’s go with page path. And then a category if you have multiple timing
hits, I’m just going to call this back to SERP time. And that’s really it, then you have to send
it to the right account. You can enter your tracking ID here, I already
have that saved in a Google Analytics variable and attached to trigger that we have just
created back to SERPs right her. Let’s save this and refresh our preview
and debug mode. See if everything works. Let’s go back to our page and click on the
search result. You get our GREF here. We go back, something else fires and sends
over the information and we have redirected back to our Google search result. Now, we couldn’t really see what data was
sent over to Google Analytics, you can’t also not really see that in the tag assistant,
unfortunately. Also, our real-time reporting doesn’t have
any information about the timing events that we actually sent over. And therefore, to inspect this, we could build
in just to see again, something into our listener right here before the user is sent back. Let’s stop the browser again with an alert
statement saying simple stop, refresh this and go back to our page. Again, we’ll go through the exercise of clicking
on our search result. GREF is appended, we click on the back button,
and we are stopped. Now what we already can see, unfortunately,
browser’s completely stopped at this point. We can already see that there is the right
event fired. And if you open up our preview and debug mode,
unfortunately, can’t do anything here. Let’s try this again. This time, I’m going to simply take out this
window history event. Let’s get rid of the alert. That’s a better way to test this, refresh. And we’re going to go back to our page, click
on the back button. Now we are not redirected but we can see that
there was an event in the data layer, return to SERP. Our GA timing hit was fired. And if we had the GA debugger enabled, which
I haven’t yet. So let me just go back and go through the
exercise again. And now I’m going to open up my developer
console here. And through this GA debugger extension, we
have some great information inside of our console here. And we should be able to see what data was
sent over. So first of all, there was a page view sent,
and then, later on, there should be a timing hit sent. That actually has our variable of the homepage. And then the timing value of around five seconds. Tthe label is not defined, which is fine as
well. So this all works as expected. Again, in Google Analytics, we can see that
data inside of the real-time reporting, we will need to wait till we get some data in
in order to build our reports. Now, how do you build such a report that you
can later look at? Inside of your customizations up here, you’ll
find your custom reports, which you can create. And you simply need to go with a new custom
report. It depends how you want to look at the data,
but I will go with a flat table here. I’m going to call this Back to SERP Timing
report. And as the dimension, we want to simply get
our timing variable that we had entered at the beginning. And as the metric again, we will put in timing,
we have the average user timing available to us, which we then can use to build our
data set. So let’s save this. We have just created this so will not be any
data in here. Ahh, we already have data in here so here
we go. The homepage, so the average time the user
spends on the page before he goes back to the search engine result pages is 4.2 seconds. So ready data in here. And this is how you can build that report
as well. All right, so there you have it. This is how you can track dwell time with
the help of Google Tag Manager and Google Analytics. Now you need to be a little bit careful here
because this is a little bit of a techie technique. We are misusing the browser API to track a
metric in outside of our Google Analytics. And normally, the browser history API is used
for manipulation of the history, especially on single page websites. So be aware that you need to test this very
thoroughly before you put this into production. And talk to your developer if there are any
concerns if browser history API is used. But nonetheless, I think it’s a great use
of the data different components of Google Tag Manager to track that metric and really
props to Simo to come up with this way on how to track this with the help of Google
Tag Manager. Now, I’d love to hear from you. Is dwell time something you’re going to build
into your system? Is that something you pay attention to when
you try to influence the search engine result? Is that something you pay attention to in
your SEO efforts? Please leave us a comment down below and let
us know how you think about dwell time. And if you haven’t yet, then maybe consider
subscribing right over there because we bring you new videos just like this one every week. Now my name is Julian. Till next time.

21 thoughts on “How to #measure SEO Dwell Time with Google Analytics and Google Tag Manager

  1. Jorden Pharaoh Post author

    IG: Modern_Entertainment ……… love the video :)!

  2. David Hollands-Hurst Post author

    Thanks, Julian. I am setting this up as a test for a few clients to see if it gives us some actionable insights. I will let you know.

  3. Cody Albright Post author

    Thanks for the video, Julian!

    Quick question: What happens when somebody opens up the link from the Google SERP, believes that they didn't like what they saw or they were done with the page, and then closes the tab not instead of hitting the back button? Would the history change with "popstate" be applicable here?

  4. K Md Post author

    Sir, thank you very much, I have one question, while am using Google tag Manager, it's increase page size from kb to mb, how to decrease page size

  5. Ben Carew Post author

    Very interesting implementation. Is it necessary to comment out the code and test it incrementally do you think? Or can we simply copy-paste it and set up the tags as shown?

  6. Michael Eugene Romero Post author

    Where did you get that pospate in 11:20

  7. John Coleman Post author

    yes thank you very much. For me the gref gets added and then stripped away during page load. Does anyone have any tips where I should look to solve that? Because it gets stripped off, the timing recording doesn't get triggered. It's a wix site with some html iframes linking to eventbrite. Also, the History API seems to be not supported when I run it in my browser (latest Chrome).

  8. suriam noidor Post author

    Hi Julian. Thank you for another great video! One question: would this work if someone has SERP results open by default in a new tab? In this case there is no back button. User simply closes tab and returns to SERP for a new search.

  9. Dan Thompson Post author

    Julian, great video. I implemented this and it is working well for Google Organic clicks. Is there a way to use this for clicks coming from Google Ads (formerly Adwords)?

  10. vinod patil Post author

    If the user closed the tab instead of pressing back button, this tag won't measure the dwell time, correct?

  11. Krzysztof Skubacz Post author

    Great video Julian! Any advanced metrics that can be used to help in SEO are more than velcome 🙂

  12. Mehdi Mohammadi Post author

    Hi Julian, I have implemented this but not getting the data in GA, I have looked at my debugger, I can see the call to GA is firing but failing, I get "IO: Stream cancelled by CLIENT " error message and 301 code, can you help me out please?

  13. Krystian Manthey Post author

    Hi Julian, awesome video. I wondered if I also can track the amount of visitors who clicked the "return to serps" button? I guess to compare this with total visitors will give me better information about the effect of changes of my site. Because decreased "returners" means propably a good change.

  14. achryl Post author

    Thank you for this, you rock!! One concern is that outliers, like someone staying for 30 minutes, could skew the result. Is it possible to make an median time on page rather than average?

  15. StaceySolomonMusic Post author

    Hi Julian, really enjoying learning about GTM from you. I have implemented the TAG in this lesson but get Validate Container messages when I try to use it on my Joomla website. Any ideas why?
    Unknown Variable Name 

    Listener – SERP Bounce 

    Unknown variable 'DLV – gtm.start' found in a tag. Edit the tag and remove the reference to the unknown variable.

    Unknown Variable Name 

    Listener – SERP Bounce 

    Unknown variable 'New History Fragment' found in a tag. Edit the tag and remove the reference to the unknown

  16. Sachin Shelar Post author

    Hi Julian Thanks for this great video. But when i am configuring it is showing below error while previewing.

    "Unknown variable 'Old History Fragment' found in a tag. Edit the tag and remove the reference to the unknown variable."

  17. Mariusz Kowalczyk Post author

    Hey Julian, any idea where can I find Timing Category, Label, and Variable? I don't see them in Dimensions 🙁

  18. Web Master Post author

    that piece of code is not working . got an error
    "Unknown variable “DLV – gtm.start” found in a tag. Edit the tag and remove the reference to the unknown variable.

    Unknown variable “New History Fragment” found in a tag. Edit the tag and remove the reference to the unknown variable.

    Unknown variable “Old History Fragment” found in a tag. Edit the tag and remove the reference to the unknown variable.



Leave a Reply

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