Leo Jiang
Leo Jiang

Reputation: 26243

Loading Google Analytic's gtag.js using Webpack after everything else loads

If I load Google Analytics like they recommended, everything works:

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

  gtag('config', 'UA-123');
</script>

However, I want to load GA after everything else loads and runs. My project uses Webpack and React, so I wanted to use Webpack's dynamic imports after React mounts:

initGoogleAnalytics.js:

import { GA_ID } from 'settings';

export default () => {
  window.dataLayer = window.dataLayer || [];
  window.gtag = (...args) => window.dataLayer.push(args);
  window.gtag('js', new Date());
  window.gtag('config', GA_ID);

  if (process.env.NODE_ENV === 'production') {
    const script = window.document.createElement('script');
    script.async = 1;
    script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_ID}`;
    const elem = window.document.getElementsByTagName('script')[0];
    elem.parentNode.insertBefore(script, elem);
  }
};

Component:

componentDidMount() {
  initGoogleAnalytics();
}

However, this doesn't log anything. It also doesn't make any network requests, aside from loading gtag/js.

How can I load GA after React mounts?

Upvotes: 1

Views: 1961

Answers (1)

Leo Jiang
Leo Jiang

Reputation: 26243

I found the problem. Google Analytic's code was:

function gtag(){dataLayer.push(arguments);}

I changed it to:

window.gtag = (...args) => dataLayer.push(args);

However, GA expects an arguments object because it uses arguments.callee.

Upvotes: 1

Related Questions