DEV Community

Cover image for Google Analytics on React.js Components
Basile
Basile

Posted on • Edited on

Google Analytics on React.js Components

Intro

Struggling to use Google Analytics on a React-app?
Do you only get data on the landing page of your app, instead of every page?

This article will be about how to fix this problem!

The issue:

Google Analytics (GA) sends a pageview per page load, this means that if you would go on a certain page on your website, it requests that page from the server and loads it for the user. That is what GA records and sends as data.

(This is in the case of a simple page view, page-events will not be discussed here!)

And this is also what is the issue when trying to use GA on a React-app (or any single-page applications). React will load the whole app at once and switch components directly on the browser side.

GA doesn't see this as a new page-load as it doesn't actually load a new page, but as a reload of the same page.

A solution:

There have been different kinds of solutions to this problem, but when I went looking for one I found it confusing to find a clear and up-to-date solution. So here I am, sharing my own recommendation!

The idea would be that, as GA recognizes the page reload of the root URL (yourwebsite.com/path/to/page) but not the URI (That is the part after the root: yourwebsite.com/path/to/page), the trick would be to make it check that URI everytime it reloads. And send that as the whole location of the page.

This solution requires you to use those dependencies:

  • react-router-dom and react-ga
npm -i react-router-dom react-ga --save
or
yarn add react-router-dom react-ga --save
Enter fullscreen mode Exit fullscreen mode

Create a file in your source folder and give it a name like useGaTracker.js or something, you can name it however you want though.

image

STEP 1

  • Go get your UA tracking code on GA.

If you already have created your GA property, you can find that code like this:

  • Go to Admin image
  • Select the property you are using - and click on Property Settings image
  • Copy your Tracking ID (should start with UA-xxxxxxx-x) image

STEP 2

  • Import { useEffect, useState } from react; { useLocation } from react-router-dom and ReactGA from react-ga inside the useGaTracker.js file.
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import ReactGA from "react-ga";
Enter fullscreen mode Exit fullscreen mode

STEP 3

  • Let's wright the function:
const useGaTracker = () => {
    const location = useLocation();
    const [initialized, setInitialized] = useState(false);

    useEffect(() => {
        if (!window.location.href.includes("localhost")) {
        ReactGA.initialize("UA-xxxxxxxxx-x");
        }
        setInitialized(true);
    }, []);

    useEffect(() => {
        if (initialized) {
        ReactGA.pageview(location.pathname + location.search);
        }
    }, [initialized, location]);
};

export default useGaTracker;
Enter fullscreen mode Exit fullscreen mode

useLocation() is what we will use to get our routing as location.

The first useEffect() will check if your project is running on a localhost, if not, it will initialize your Tracking ID in the ReactGA and set the state initialized to TRUE.

The Second useEffect() will send the pageview to GA with it's location.

This one will also know to send that information each time initialized or location has changed.

STEP 4

  • Import this function into our routing file.

Go to the file that you use to route your components, and add your function in the router-component (in my case this would be my app.js file:

App.js
import { Route, Switch, Redirect } from 'react-router-dom'
import useGaTracker from './useGaTracker'

const App = () => {

  useGaTracker();

  return (
    <div className="App">
       <Switch>
          <Route path="/" exact component={ Landing } /> 

          <Route path="/about" exact component={ About } />
          <Route path="/discord" exact component={ Discord } />

          <Route path="/404" component={ Error } />
          <Redirect to="/404" />
       </Switch>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Finally

  • That's about it!

You should have a working connection that will save and send all the different routes you use in your routing file!

Basile&Code

Top comments (7)

Collapse
 
redboy18x profile image
redboy18x

setInitialized(true);

This statement should be in if block.

useEffect(() => {
if (!window.location.href.includes("localhost")) {
ReactGA.initialize("UA-xxxxxxxxx-x");
setInitialized(true);
}
}, []);

Collapse
 
ilariacallegari profile image
Ilaria • Edited

In my case, using the useGaTracker hook in the routing component was not working, as the location returned undefined. I had to implement the hook in every page in order for it to work properly.

Collapse
 
samthewebdev profile image
Sam Kautz

Hi Ilaria, thanks for clarifying on this! There is very little info out there on this and it can get frustrating! Would it be possible for you to clarify just a bit on how you managed to do this? Maybe show one example page where you implemented the hook? I know I sound super green but I'm still getting the same error and I'm sure I'm missing something.

Thanks!

Collapse
 
ilariacallegari profile image
Ilaria

Hi Sam, well long time has passed and in all honesty I don't really remember how I did it, but I had a look at the project where I was using this package and what I did was calling the useGaTracker hook in every page component like so - after importing it:

const Contact = () => {
useGaTracker();
const [ref, inView] = useInView();
const { getInTouchCtn, headingCtn, heading, descriptionCtn, linkCtn, link } =
useStyles(inView);
return (

.... etc etc

Also note, that the implementation of the hook in the article is not 100% correct - inside the first useEffect, setInitialize(true) should be inside the if statement, not outside:

useEffect(() => {
if (!window.location.href.includes("localhost")) {
ReactGA.initialize(${process.env.REACT_APP_GA});
setInitialized(true);
}
}, []);

You can have a look at my GitHub repo: github.com/IlariaCallegari/ilariac...

I just noticed that for some strange reason - probably exhaustion ehehe - I put the useGaTracker hook in src/utils, so head there if you want to see the hook implementation. And if you go into src/pages you can see how I called the hook.

Hope this helps!
Ilaria

Collapse
 
javierpineros profile image
Javier Piñeros

Hello Basile, can you indicate the versions of react, react-router-dom and others module used?

What you indicate does not work for me and the following error is generated

useLocation
/node-projects/modules/hooks.js:29
26 | );
27 | }
28 |

29 | return useContext (Context) .location;
30 | }
31 |
32 | export function useParams () {

Thanks!

Collapse
 
ilariacallegari profile image
Ilaria

not sure it is still useful, but try implementing the hook in every page, rather than only in the routing component. I had the same error, and it worked after doing this.

Collapse
 
vighnesh profile image
Vighnesh Kulkarni

Thanks Basile!