Google tag manager, out of the box, is unable to track React js page navigations using
This article explains three ways to integrate Google Tag Manager with React Js.
In this method, I place the GTM scripts in the index.html file located in the public folder. Use the
Here is my
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Google Tag Manager - as high in the <head> of the page -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
<title>React App</title>
</head>
<body>
<!--immediately after the opening <body> tag-->
<noscript><frame src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<div id="root"></div>
</body>
</html>
The next step is to create a history change trigger. Proceed to this step to create a history change trigger in the GTM console. Now my app is all set to track page views.
There is an npm package to integrate GTM with React Js. It is called
I can install the package by running
npm install
or
by editing the
Now I must place the tracking code in the application. The same rule applies to the tag manager scripts, but I cannot select
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import TagManager from 'react-gtm-module';
import Users from './Users'
import Posts from './Posts'
import Login from './Login';
const App = () => {
useEffect(() => {
TagManager.initialize({ gtmId: 'GTM-XXXXX' });
}, []);
return (
<BrowserRouter>
<React.Fragment>
<Route path="/" component={Users} exact />
<Route path="/posts" component={Posts} exact />
<Route path="/login" component={Login} exact />
</React.Fragment>
</BrowserRouter>
);
}
export default App;
The next step is to create a history change trigger. Proceed to this step to create a history change trigger in the GTM console. Now my app is all set to track page views.
I modified the GTM script so I could call it directly. Then I created a separate file to place my modified analytics script. My modified script is in Typescript, which is helpful for most users.
export const analytics = ((w: Window, d: Document, s: string, l: string, i: string) => {
(w as any).dataLayer = (window as any).dataLayer || [];
(w as any).dataLayer.push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var dl = l != 'dataLayer' ? '&l='+l : '';
var scr = 'https://www.googletagmanager.com/gtm.js?id='+i+dl;
/*
To avoid Multiple installations of google tag manager detected warning
*/
if(!scriptExists(scr)) {
var f = d.getElementsByTagName(s)[0],
j: HTMLScriptElement = d.createElement("script")
j.async = true;
j.src = scr;
f?.parentNode?.insertBefore(j,f);
}
})
const scriptExists = (url: string) => {
var scripts = document.getElementsByTagName('script');
for (var i = scripts.length; i--;) {
if (scripts[i].src == url) return true;
}
return false;
}
Now I must call this function whenever the user clicks a link. Therefore, I need a common page shared by all web application pages.
useEffect(() => {
analytics(window, document, 'script', 'dataLayer', 'GTM-AA12345');
},[])
That's it. I don't need to implement a history change trigger with this method.
Now it's time to create a history change trigger in the Google tag manager console. Log into google tag manager and follow the below steps.
Don't forget to publish your workspace container. Now you would see a history change trigger for navigations within your application.
We can use Google tag assistant to ensure all the intended triggers are triggered on your page navigations. To start a debug session, click the Preview button on the top right. Once you click start, the tag manager will open a debug window connected to your website. If it fails to connect the debugger to your website, close the tab and restart the debug session. I have experienced this issue several times. Once the session is successful, use the window to navigate your website links. You will notice the history trigger fires on each navigation.
The easiest way to ensure your website tags are triggered is to install the Google tag assistant chrome extension. Tag assistant will also tell you if you have any duplicate tag issues. Install it from https://get.google.com/tagassistant.
React js uses the virtual dom concept to update the view efficiently compared to traditional dom-manipulation technics. React updates only the necessary parts of the dom, leaving the rest of the dom unchanged. Therefore, clicking on a react <Link/> and a traditional <a href/> behave differently.
React js Link is derived from the
Using the traditional anchor tag in place of the react Link would result in the entire page load regardless most of the page content remains the same.
The main advantage of the react Link is performance due to efficient dom manipulation. As I mentioned earlier, the changes are compared in the virtual dom and update only necessary elements in the real dom, avoiding a total dom re-render.
One potential drawback is external javascript execution. The javascript files you import in your application and javascript code reside inside the page header or body is executed only once. That's when you enter the page by typing the URL or any way that causes a full page load. And this is also the reason why Google analytics does not track your internal page navigations.