DEV Community

Cover image for Add Google Analytics through GTM (Google Tag Manager) on Next.js

Add Google Analytics through GTM (Google Tag Manager) on Next.js

Flamur Mavraj on July 28, 2020

Last week we released a brand new website (https://uwork.no) for our amazing client (uWork AS) and had to get Google Tag Manager (GTM) up and runni...
Collapse
 
cullylarson profile image
Cully Larson

Is there some significance to the name of the page parameter you're including in the event object? I don't see that parameter documented anywhere and you don't specifically reference it when creating your trigger.

Collapse
 
cullylarson profile image
Cully Larson

I tested without including the page parameter and it works the same. It seems like page isn't necessary.

Collapse
 
oxodesign profile image
Flamur Mavraj

Well the property it self is not required but I think its important to include it. The reason for it is to know what pages the user visits. Without it you are just (unless GTM can figure out this automatically) you only get the counts.

More info regarding the page you can find here:
developers.google.com/analytics/de...

Thread Thread
 
cullylarson profile image
Cully Larson

Oh, nice find. I couldn't find documentation on that parameter; I assumed it wasn't an actual GTM param. Yeah, if you leave it empty GTM figures it out. I was thinking that might be a better option, since it reduces the chance that you set it incorrectly.

Collapse
 
hukken profile image
Øystein Hukset

Hi. Great tip!
But I see a problem on my end using this method. The GTM script renders multiple times (for each Page Change). Does not matter if I use the Custom Event trigger or the History Change trigger.

Anybody else seeing this?

Collapse
 
oxodesign profile image
Flamur Mavraj

Sorry for late reply, no, haven't encounter this issue. Check if the component is rerendering and therefor firing multiple GTM page view events!

Collapse
 
mog profile image
Morgan Feeney

Every time I have delved into this issue, it turned out that pageProps fires after the router events, so this implementation (even though its recommended by Next.js examples) only does one job: tracking a page view.

If you want to start pushing data into the dataLayer via pageProps it is limited.

I wrote about this here: morganfeeney.com/how-to/integrate-..., you're welcome.

Collapse
 
mcasey8540 profile image
Mike Casey

Awesome article, very helpful to learn how to properly setup GTM with nextjs.

My only recommendation would be to setup the new Google Analytics G4 instead of Google Analytics Universal, support.google.com/analytics/answe...

Collapse
 
oxodesign profile image
Flamur Mavraj

I have to take a closer look at it! But quite satisfied with the GA Universal. I use custom events to handle all cases! I even implemented virtuell page view (handling submit forms on react/next.js)

Collapse
 
dbredvick profile image
drew.tech

I did this awhile back and forgot to make the event "non-interactive" and our bounce rate dropped a TON.

Oops 😅

Collapse
 
roseline124 profile image
Hyunji Song

our service, too 😢

Collapse
 
oxodesign profile image
Flamur Mavraj

Oopsi indeed!

Collapse
 
alex44lel profile image
Alex44lel

Hi I have done everything in this post but there is a problem.

When a user logs-in on my website it gets redirected to another page (using router.replace()). The problem is that the pageview event is triggering two times when a user logs-in and thus registering two pageviews instead of one.

I attach a photo of my google tag manager

Hope anybody can help me as I do not want to have "fake" pageviews on my analytics

Collapse
 
oxodesign profile image
Flamur Mavraj

Havent had this scenario, so not sure what you can do here! If you have found a solution please do share it with us.

All the best.

Collapse
 
the_yamiteru profile image
Yamiteru

How should the _document component look like as a FunctionComponent?

Also is there any difference in injecting the tags in _document or NextHead?

Collapse
 
benbalderas profile image
Ben Balderas

I've tried this and it seems to work in next/head. I have a Layout component which has a Head, and this is used in every page. Placing the script in there should also work.

But I guess placing it in _document is best since this ensures the script is always on all pages.

Collapse
 
the_yamiteru profile image
Yamiteru

Yeah I did the same but forgot to add the general Page component to every page so I was missing the script in some of my pages.

Collapse
 
spencermarx profile image
Spencer Marx

Nice article Flamur!

In case you or anyone else here wants an example of how to implement GTM and Consent Mode in NextJS 15 (App Router) feel free to check out the following article 🚀

Happy developing 🧑‍💻⚡

Collapse
 
toyurc profile image
Adebayo-Ige Toyosi

I have been having this same issue for a while now, thanks a lot for this

Collapse
 
oxodesign profile image
Flamur Mavraj

You are welcome!

Collapse
 
dahrougomar profile image
Omar Dahroug

Hi Flamur, thanks for your blog. I'm currently building a next.js application and would like to load GTM only AFTER the entire page is loaded. The goal behind this is to improve the website performance. Have you figured out a way how I can run third-party JS code only after my application has loaded?

Collapse
 
abranhe profile image
Abraham Hernandez

Thanks for this!!!!!

Collapse
 
oxodesign profile image
Flamur Mavraj

You are welcome :)

Collapse
 
brun0xff profile image
brunoathaíde

Is it still necessary to do this whole process? I read in some article that GA4 is smarter and doesn't need all this configuration in SPA

Collapse
 
forhadhossenbabu profile image
Forhad Chowdhury

Thank you so much, man. You've saved my time.