logohahid

Load Google Analytics (Gtag) Efficiently In Gatsby Site

September 11, 2021
3 min read

Working with the gatsby.js site and google analytics is a little bit tricky if you consider performance. With the latest lighthouse version (v6 and above), performance reduces a lot if you have Google Tag Manager (especially if you install gatsby-plugin-google-analytics). A few months back, I even removed analytics from one of my sites as I was obsessed with performance.

But I didn’t want to remove analytics from my newly built site and didn’t want to reduce the performance too. So, I started researching for a solution and found a way to delay loading the analytics script here. I modified the script to match the new gtag script setup. It injects the gtag script after a certain period or if a user starts interacting with the site.

Setting up gtag

We need to add the following script in our gatsby-browser.js file. Here we are using an environment variable to hide our google analytics tracking id. You should add a .env file and provide the value for GATSBY_GA_TRACKING_ID there. You can adjust the script loading delay in the onreadystatechange method (I got the best result for 3500 ms).

function initGTM() {
    if (window.isGTMLoaded) {
        return false;
    }

    window.isGTMLoaded = true;

    const script = document.createElement('script');

    script.type = 'text/javascript';
    script.async = true;
    script.src = `https://www.googletagmanager.com/gtag/js?id=${process.env.GATSBY_GA_TRACKING_ID}`;

    script.onload = () => {
        window.dataLayer = window.dataLayer || [];
        function gtag() {
            dataLayer.push(arguments);
        }
        gtag('js', new Date());

        gtag('config', `${process.env.GATSBY_GA_TRACKING_ID}`);
    };

    document.head.appendChild(script);
}

function loadGTM(event) {
    initGTM();
    event.currentTarget.removeEventListener(event.type, loadGTM);
}

exports.onClientEntry = () => {
    document.onreadystatechange = () => {
        if (document.readyState !== 'loading') {
            setTimeout(initGTM, 3500);
        }
    };

    document.addEventListener('scroll', loadGTM);
    document.addEventListener('mousemove', loadGTM);
    document.addEventListener('touchstart', loadGTM);
};

Add tracking ID on GitHub Action env

I am using GitHub Action to automate the deployment of my site. So, I have to read the environment variable from the deployment server. We can provide a .env file in our project, but this will not be secure. We can use GitHub’s project secret to hide our credentials/secrets. Navigate to your project’s settings page and go to the Secrets page from the menu. Now, add a repository secret named GATSBY_GA_TRACKING_ID and provide your tracking id as a value.

In your workflow configuration file add a section called env. In the env section add the environment variable like shown below. You should keep in mind that, env section should come before the jobs section in your workflow configuration.

name: GitHub Pages

on:
  push:
    branches:
      - main

env:
  GATSBY_GA_TRACKING_ID: ${{secrets.GATSBY_GA_TRACKING_ID}}

jobs:
  deploy:
  ......
  ......

Hard Lesson

If you want to access the environment variable in the BROWSER in a Gatsby site, prefix your variable name with GATSBY_.

Thanks a lot for reading the post, and please share if you find it useful.

Gatsby Google Analytics