reactjsgoogle-analyticsgatsbyreact-helmetgatsby-plugin

How to Add multiple Tracking ID for Google Analytics in Gatsby.js?


I used gatsby-plugin-google-gtag earlier in my gatsby project to add 2 Google Analytics tracking ID and it was working fine but unfortunately, my project already has gatsby-plugin-google-analytics which doesn't support multiple tracking ID like the gtag plugin shows in docs. So I found an article where they say to put it inside the html.js file so in the docs here of Customizing-html.js i copied my file to src/ using cp .cache/default-html.js src/html.js now I want to know where to put the script which I got from google analytics... Also, I have react-helmet installed.. so which way to use to put script?

  1. manually in head? like so -

import React from "react";
import PropTypes from "prop-types";

export default function HTML(props) {
  return (
    <html {...props.htmlAttributes}>
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="x-ua-compatible" content="ie=edge" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no"
        />
        {props.headComponents}

        <script
          async
          src="https://www.googletagmanager.com/gtag/js?id=UA-123456789-1"
        />
        <script
          dangerouslySetInnerHTML={{
            __html: `
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());

          gtag('config', 'UA-123456789-1');
          `,
          }}
        />
      </head>
      <body {...props.bodyAttributes}>
        {props.preBodyComponents}
        <div
          key={`body`}
          id="___gatsby"
          dangerouslySetInnerHTML={{ __html: props.body }}
        />
        {props.postBodyComponents}
      </body>
    </html>
  );
}

HTML.propTypes = {
  htmlAttributes: PropTypes.object,
  headComponents: PropTypes.array,
  bodyAttributes: PropTypes.object,
  preBodyComponents: PropTypes.array,
  body: PropTypes.string,
  postBodyComponents: PropTypes.array,
};

OR tbh Idk where in html.js I have to insert this.. in body maybe?

<Helmet>
      {/* other stuff... */}

      {/* Global site tag (gtag.js) - Google Analytics  */}
      <script async src={`https://www.googletagmanager.com/gtag/js?id=${googleAnalyticsId}`}></script>
      <script>
        {`
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());
          gtag('config', "${googleAnalyticsId}");
        `}
      </script>
</Helmet>

Would appreciate any help or article links to read from, as i'm very new to google analytics.. I already have one tracking code in my gatsby.config.js file like so { resolve: "gatsby-plugin-google-analytics", options: { trackingId: "UA-123456789-3", head: true, anonymize: true }, }, just need help putting the 2nd tracking code in.


Solution

  • Google Analytics script should be added inside the <head> tag. Ideally, this is automatically handled by the plugins. In fact, it's exactly what {props.headComponents}, {props.preBodyComponents} and {props.postBodyComponents} does, they manipulate Gatsby's SSR API onRenderBody to place the scripts you add in the gatsby-config.js or manually in the gatsby-ssr.js.

    If you are not able to add several instances of gatsby-plugin-google-analytics or add multiple tracking identifiers using Google Tag Manager, you can use the html.js as you are doing. In this case, you should do something like:

    import React from "react";
    import PropTypes from "prop-types";
    
    export default function HTML(props) {
      return (
        <html {...props.htmlAttributes}>
          <head>
            <meta charSet="utf-8" />
            <meta httpEquiv="x-ua-compatible" content="ie=edge" />
            <meta
              name="viewport"
              content="width=device-width, initial-scale=1, shrink-to-fit=no"
            />
            {props.headComponents}
    
            <script
              async
              src="https://www.googletagmanager.com/gtag/js?id=UA-123456789-1"
            />
          <script async src={`https://www.googletagmanager.com/gtag/js?id=${googleAnalyticsId}`}></script>
          <script>
            {`
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', "${googleAnalyticsId1}");
            `}
          </script>
          <script>
            {`
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', "${googleAnalyticsId2}");
            `}
          </script>
          </head>
          <body {...props.bodyAttributes}>
            {props.preBodyComponents}
            <div
              key={`body`}
              id="___gatsby"
              dangerouslySetInnerHTML={{ __html: props.body }}
            />
            {props.postBodyComponents}
          </body>
        </html>
      );
    }
    
    HTML.propTypes = {
      htmlAttributes: PropTypes.object,
      headComponents: PropTypes.array,
      bodyAttributes: PropTypes.object,
      preBodyComponents: PropTypes.array,
      body: PropTypes.string,
      postBodyComponents: PropTypes.array,
    };
    

    Because you already have access to the <head> tag directly, there's no reason to use Helmet component, which purpose is to expose and add inside the <head> tag whatever wraps in any component. In this case, you have access directly to it so just add it there.

    Once done, and because you are adding the tracking identifier manually, you can get rid of gatsby-plugin-google-analytics and the related unused plugins.