Allow google analytics to load only after consented in Next.js

Viewed 2422

I integrated google analytics to next.js - to say, I followed these guides:

  1. https://frontend-digest.com/using-nextjs-with-google-analytics-and-typescript-620ba2359dea
  2. https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics

Which works just fine, now the issue is I need to allow loading google analytics only after cookie consent, I store my cookie consent in localStorage at the moment simply in the format:

checkboxValues = {
  necessary: true,
  statistics: false,
  marketing: false,
};

Now I need to check localStorage.getItem('acceptCookies'); and make sure google analytics is loaded only when statistics: true.

import Document, { Html, Head, Main, NextScript } from "next/document";

import { GA_TRACKING_ID } from "../utils/gtag";

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
          />
          <script
            dangerouslySetInnerHTML={{
              __html: `
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', '${GA_TRACKING_ID}', {
                page_path: window.location.pathname,
              });
          `
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

for me to check for the localStorage before render() is not possible as localStorage is only available after componentDidMount. Stuck with this, any direction?

1 Answers

there are built-in consent functions: https://developers.google.com/gtagjs/devguide/consent

so you in your case add

gtag('consent', 'default', {
  'analytics_storage': 'denied'
});

So it'll look something like:

    <script
        dangerouslySetInnerHTML={{
          __html: `
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
//this defaults to denying
    gtag('consent', 'default', {
      'analytics_storage': 'denied'
    });
          gtag('js', new Date());
//check for consent, you'll need to write your own function here, but you get the idea
if(consentGranted){
    gtag('consent', 'update', {
      'analytics_storage': 'granted'
    });
  }
        gtag('config', '${GA_TRACKING_ID}', {
            page_path: window.location.pathname,
          });

          `
            }}
          />

Alternatively, you could just wrap the "config" to line in the similar consent line, though this might not be as a "complete" solution as it only stops the pageview:

if(consent){    
gtag('config', '${GA_TRACKING_ID}', {
            page_path: window.location.pathname,
          });
    }
Related