BlogWorkAboutFree ToolsNewsletter
BlogWorkAboutFree ToolsNewsletter
All articles

Custom hook to connect Google Analytics in React

Create a custom hook to connect Google Analytics in React using react-router-dom and react-ga packages

Written by Jim Raptis

Aug 6, 2020 • 3 min

Custom hook to connect Google Analytics in React

A quick explanation of what we want to achieve.

Google Analytics is a web analytics service offered by Google that tracks and reports website traffic. They offer a great dashboard and the service is free.

Our goal is to connect the Google Analytics to our React app using some utility functions and a custom React hook that handles the initialization of the ga object.

Installation

We start with the creation of a new React app using create-react-app and npx:

npx create-react-app demo-app
cd demo-app

Then, we install the two dependencies. The react-router-dom library is the de-facto routing solution in React. and react-ga the official Google Analytics React package:

yarn add react-router-dom react-ga

Or if you're using npm:

npm install --save react-router-dom react-ga

Create the analytics.js file

Our first step is to create the file analytics.js where we're going to create the Google Analytics init function and define two helpers to fire custom events and the pageview one.

We utilize the react-ga method initialize to set up the Google Analytics with our unique tracking id. You can pass more options to the initialize function but we'll only enable debug logging for the local development mode.

Then we create the two extra helper functions, sendEvent() and sendPageview(), that simply fire a custom event and the pageview one respectively.

import ReactGA from "react-ga"

const TRACKING_ID = "UA-XXXXXXXXX-X"

function init() {
  // Enable debug mode on the local development environment
  const isDev = !process.env.NODE_ENV || process.env.NODE_ENV === "development"
  ReactGA.initialize(TRACKING_ID, { debug: isDev })
}

function sendEvent(payload) {
  ReactGA.event(payload)
}

function sendPageview(path) {
  ReactGA.set({ page: path })
  ReactGA.pageview(path)
}

export default {
  init,
  sendEvent,
  sendPageview,
}

Define the App component

Now we have to create the App component that renders the pages of our app. To keep it simple, I define 3 dummy routes, /, /features, and /signup.

I use BrowserRouter over the pure Router because it ignores the history prop and handles the history object automatically for you.

The Switch component selects the first route that fits the location and renders it. So it renders only one route!

import React from "react"
import { BrowserRouter, Switch, Route } from "react-router-dom"

import Home from "./pages/Home"
import Features from "./pages/Features"
import SignUp from "./pages/SignUp"

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route exact path="/features">
          <Features />
        </Route>
        <Route exact path="/signup">
          <SignUp />
        </Route>
      </Switch>
    </BrowserRouter>
  )
}

export default App

Build the custom useGoogleAnalytics hook

Since we don't handle history manually (BrowserRouter does this for us), our only option to access the current location object is by using the useLocation hook by react-router-dom.

So, we define two useEffect hooks. The first useEffect simulates the known componentDidMount function and initializes the ga object. The second one listens on every location change and sends the valuable pageview event.

Pretty straightforward, huh?!

import React from "react"
import { useLocation } from "react-router-dom"

import analytics from "./analytics"

export default function useGoogleAnalytics() {
  const location = useLocation()

  React.useEffect(() => {
    analytics.init()
  }, [])

  React.useEffect(() => {
    const currentPath = location.pathname + location.search
    analytics.sendPageview(currentPath)
  }, [location])
}

Let's call our hook

We go to our App component and we call our custom hook function.

function App() {
  useGoogleAnalytics()

  return (
    <BrowserRouter>
      <Switch>...</Switch>
    </BrowserRouter>
  )
}

There is a problem though. Our hook depends on the current location object which is not available yet on the App components

A quick solution is to create a separate component called Routes that renders the Switch component and its children and calls the custom hook from there.

By doing that we can be sure that the BrowserRouter component exists and has defined the location object before rendering Routes.

function Routes() {
  useGoogleAnalytics()

  return (
    <Switch>
      <Route exact path="/">
        <Home />
      </Route>
      <Route exact path="/features">
        <Features />
      </Route>
      <Route exact path="/signup">
        <SignUp />
      </Route>
    </Switch>
  )
}

function App() {
  return (
    <BrowserRouter>
      <Routes />
    </BrowserRouter>
  )
}

That's all folks! You have successfully added Google Analytics to your React app!

Now, you can fire custom events from any component you like by just importing and calling the sendEvent function from the analytics.js file.

If you liked this post, you can follow me on Twitter where I share daily tips about bootstraping, product development, and UI/UX design tips.

More articles like this:

Jim Raptis

© 2024

RECOMMENDED