DEV Community

Cover image for React: enable Google Analytics after a user grants consent
Katsiaryna (Kate) Lupachova
Katsiaryna (Kate) Lupachova

Posted on

React: enable Google Analytics after a user grants consent

Originally published on my personal blog

Introduction

While working recently on one of the web apps, one of the customer requirements was to track user's activity on the website is only after and if a user gave his/her consent to do so.

This blog post is about my approach to this problem.

Add Google Analytics to React project

The simpliest way to add Google Analytics to any React project is to use React-GA library. Add it by running:



npm install react-ga


Enter fullscreen mode Exit fullscreen mode

For the code not to look messy, I prefer to create separate util files. Create ga-utils.ts file and add there helper method for Google Analytics initialization:



import * as ReactGA from "react-ga";

export const initGA = (id: string) => {
  if (process.env.NODE_ENV === "production") {
    ReactGA.initialize(id);
  }
};


Enter fullscreen mode Exit fullscreen mode

This method takes a Google Analytics tracking ID as a param and makes an initialization only in a production mode (there is no point in enabling GA in a development mode).

Add Cookie Consent

Google Analytics use HTTP Cookies to "remember" what a user has done on previous pages/interactions with the website. You can read more about it here.

Under laws like the GDPR and ePrivacy (Cookie Law), users must provide their consent before cookies can be deployed or installed on their computer.

There is a library that can be used to prompt a user to grant or decline a cookie consent - React cookie consent.

Install it by running:



npm install react-cookie-consent


Enter fullscreen mode Exit fullscreen mode

Then add CookieConsent component in the App.tsx file:



import CookieConsent from "react-cookie-consent";
import "./App.css";

function App() {
  return (
    <div className="App">
      <h1>Hello World!</h1>
      <CookieConsent enableDeclineButton>
        This website uses cookies to enhance the user experience.
      </CookieConsent>
    </div>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

If you run the app, you'll see a Cookie Consent bar at the bottom of the page with two buttons: "I understand" and "I decline".

demo

The next thing is to handle actions when a user declines or accepts cookies usage.

If a user grants permission by clicking on the "I understand" button, then Google Analytics should be initialized.



...
const handleAcceptCookie = () => {
  if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID) {
    initGA(process.env.REACT_APP_GOOGLE_ANALYTICS_ID);
  }
};
...

<CookieConsent
  enableDeclineButton
  onAccept={handleAcceptCookie}
>
  This website uses cookies to enhance the user experience.
</CookieConsent>
...


Enter fullscreen mode Exit fullscreen mode

It is a good practice to hide such values as a Google Analytics tracking ID in .env file.



REACT_APP_GOOGLE_ANALYTICS_ID=UA-XXXXXXXXX


Enter fullscreen mode Exit fullscreen mode

Actually, if a user declines cookie usage by clicking on "I decline" button, then nothing should happen. The app should run just without Google Analytics initialization. But we can delete Google Analytics cookies from a browser just in case if they somehow were written there before. This step is totally optional.



import CookieConsent, { Cookies } from "react-cookie-consent";

...

const handleDeclineCookie = () => {
  //remove google analytics cookies
  Cookies.remove("_ga");
  Cookies.remove("_gat");
  Cookies.remove("_gid");
};

...

<CookieConsent
  enableDeclineButton
  onAccept={handleAcceptCookie}
  onDecline={handleDeclineCookie}
>
  This website uses cookies to enhance the user experience.
</CookieConsent>

...



Enter fullscreen mode Exit fullscreen mode

By default, react-cookie-consent library writes a CookieConsent cookie value "true" or "false" based on a user action (accept or decline respectively). You can check this in developer tools on Application tab.

cookie

The Cookie Consent bar won't appear on the next app visit from the same browser. So we have to handle Google Analytics initialization on every app run (or website visit) if a user granted prior consent. This can be accomplished with useEffect hook and getConsentValue() function of react-cookie-consent library:



import CookieConsent, {
  getCookieConsentValue,
  Cookies,
} from "react-cookie-consent";

...

useEffect(() => {
    const isConsent = getCookieConsentValue();
    if (isConsent === "true") {
      handleAcceptCookie();
    }
  }, []);
...



Enter fullscreen mode Exit fullscreen mode

The final App.ts file is:



import { useEffect } from "react";
import CookieConsent, {
getCookieConsentValue,
Cookies,
} from "react-cookie-consent";
import { initGA } from "./ga-utils";
import "./App.css";

function App() {
const handleAcceptCookie = () => {
if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID) {
initGA(process.env.REACT_APP_GOOGLE_ANALYTICS_ID);
}
};

const handleDeclineCookie = () => {
//remove google analytics cookies
Cookies.remove("_ga");
Cookies.remove("_gat");
Cookies.remove("_gid");
};

useEffect(() => {
const isConsent = getCookieConsentValue();
if (isConsent === "true") {
handleAcceptCookie();
}
}, []);

return (
<div className="App">
<h1>Hello World!</h1>
<CookieConsent
enableDeclineButton
onAccept={handleAcceptCookie}
onDecline={handleDeclineCookie}
>
This website uses cookies to enhance the user experience.
</CookieConsent>
</div>
);
}

export default App;

Enter fullscreen mode Exit fullscreen mode




Conclusion

This is my take on handling Google Analytics initialization only after a user grants permission in a React app.

The source code is here.

Top comments (3)

Collapse
 
raptoria profile image
raptoria

this solution works great with react-ga4 github.com/PriceRunner/react-ga4

Collapse
 
andrej_gajdos profile image
Andrej Gajdos

Thanks for this blog post, but this solution is not ideal because ReactGA doesn't support GA 4 github.com/react-ga/react-ga/issue...

Collapse
 
maximilianv profile image
Maximilian Vitzthum

Thank you this method still works great! Definitely one of the best ways to handle analytics