Algobook
- The developer's handbook
mode-switch
back-button
Buy Me A Coffee
Mon Apr 03 2023

Cookie policy banner in React with Google Analytics cookie consent handling

Cookies are pretty much essential in todays world of web development. All websites that includes any type of advertisment, marketing and so on will need the use of cookies. To protect our precious visitors and to be fully transparent with what we actually use our cookies for (and for legal reasons), we should have a proper cookie policy available for everyone visiting our websites.

In this guide we will create a Cookie Policy banner in React that will be fully responsive across devices and give it some nice animation as well. We will also create logic for handling the analytics consents for Google Analytics. If you don't use Google Analytics, just skip the part we are mentioning it.

Open source lib

We are offering a complete solution for cookie consent banners that you can use in your React application. Documentation is found here.

Example of how it could look when we are done

Desktop

mobile screenshot

Mobile

desktop-screenshot

Set up Google Analytics (Optional)

  • Go to Google Analytics and set up your website.
  • When it is setup you will get a code snippet from Google Analytics that you should add to your index.html page in the <head> tag.
<head> <script async src="https://www.googletagmanager.com/gtag/js?id={YOUR_ID}" ></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag("js", new Date()); gtag("config", "{YOUR_ID}"); </script> </head>

Now Google will start tracking your user activity on your page.

Create our CookieBanner component

Let's create a CookieBanner.tsx (or .jsx) if you are using JavaScript.

We are using an icon from Google fonts. You can find it here.

import { useEffect, useState } from "react"; import styles from "./CookieBanner.module.scss"; const CONSENT_KEY = "COOKIE_CONSENT"; enum CONSENT_CODES { GRANTED = "granted", DENIED = "denied", } export const CookieBanner = () => { const [isVisible, setVisible] = useState(false); useEffect(() => { setTimeout(() => { setVisible(Boolean(!localStorage.getItem(CONSENT_KEY))); }, 2000); }, []); const onAccept = () => { (window as any).gtag("consent", "default", { analytics_storage: CONSENT_CODES.GRANTED, }); localStorage.setItem(CONSENT_KEY, CONSENT_CODES.GRANTED); setVisible(false); }; const onDeny = () => { (window as any).gtag("consent", "default", { analytics_storage: CONSENT_CODES.DENIED, }); localStorage.setItem(CONSENT_KEY, CONSENT_CODES.DENIED); setVisible(false); }; return ( <div className={`${styles.cookieBanner} ${isVisible ? styles.show : null}`}> <div className={styles.headline}> <img className={styles.icon} src="/icons/cookie.svg" alt="cookie-icon" /> <h4>Cookie policy</h4> </div> <span className={styles.text}> State some information about your cookie policy here... </span> <div className={styles.buttons}> <button className={styles.deny} onClick={onDeny}> Don't accept </button> <button className={styles.accept} onClick={onAccept}> Accept </button> </div> <div className={styles.linkContainer}> <a className={styles.link} href="/yourCookiePolicyPage"> More on how we use cookies </a> </div> </div> ); };

This is our full implementation of the cookie banner. Let's break it down into some important notes.

Notes

  • CONSENT_KEY is our constant we will use as identifier for our localStorage where we will store the consent from the user
  • enum CONSENT_CODES - Our codes for either denying or granting depending on the user choice.
  • In our useEffect() hook, we are waiting 2 seconds before changing the state. We want the first time user to get some initial feeling of our application before we start hunting for approval.
  • onAccept() - We will set the consent to granted and also make sure Google Analytics gets the information as well through the gTag() call. This function will be triggered on the accept button click.
  • onDeny() - If user don't want any cookies, we set it to denied and send the information to Google Analytics as well to prevent any cookies from them.

Let's give it some css

.cookieBanner { display: flex; flex-direction: column; position: fixed; bottom: 0; left: 0; right: 0; padding: 1rem 2rem; width: 100%; background-color: white; transform: translateY(100%); transition-duration: 3500ms; .headline { display: flex; align-items: center; gap: 0.5rem; .icon { height: 20px; width: 20px; } } .text { font-size: 14px; } .buttons { display: flex; flex: 1; padding: 1rem 0; justify-content: flex-end; align-items: center; gap: 2rem; @media only screen and (max-width: 600px) { justify-content: center; } .deny { border: none; background-color: white; color: #0069c4; font-size: 15px; font-weight: 650; } .accept { background-color: #0069c4; border: none; color: white; padding: 1rem; text-align: center; display: inline-block; font-weight: 650; font-size: 15px; width: 90px; border-radius: 4px; } } .linkContainer { display: flex; justify-content: center; align-items: center; .link { text-decoration: none; color: #0069c4; font-weight: 600; font-size: 16px; padding: 0 0 1rem 0; @media only screen and (max-width: 600px) { font-size: 14px; padding: 0; } } } } .show { transform: translateY(0%); }

There we go. Now our styling is done as well!

Some notes

  • We are using @media tags on some places to change the styling depending on device size.
  • position: fixed; is for keeping it sticked to the bottom
  • transition-duration: 3500ms; The animation slide from bottom will take 3,5 seconds. You can change this for your own preference.
  • The class .show will be triggered if isVisible in our component is set to true and the animation will start.

Outro

In todays guide we demonstrated how to create a cookie banner in React that is responsive for mobile and desktop devices, and we also gave it some animation to make the appearance a little bit nicer. We also showed how we can change the consent state for Google Analytics when the user interacts with the banner component.

I hope you found this guide helpful and good luck with your project!

signatureMon Apr 03 2023
See all our articles