0

I'm trying to add a Google Analytics config value to index.html. This value will differ from staging and production, so it should be configurable, preferrably via an env file. I've seen some answers here in SO about this, but they're all very old (4+ years), so there may be a different way in modern Angular.

Basically, I need to make the following code accept variables:

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

    gtag('config', <google analytics id>);
  </script>
  <!-- Google Tag Manager -->
  <script>
    (function (w, d, s, l, i) {
      w[l] = w[l] || [];
      w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
      var f = d.getElementsByTagName(s)[0],
        j = d.createElement(s),
        dl = l != 'dataLayer' ? '&l=' + l : '';
      j.async = true;
      j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
      f.parentNode.insertBefore(j, f);
    })(window, document, 'script', 'dataLayer', <google tag manager id>);
  </script>
1
  • 1
    What prevents you from moving this javascript to your AppComponent?
    – Pieterjan
    Commented Jun 19 at 17:07

1 Answer 1

0

I solved this issue by injecting the scripts from a service. Here's the full code:

declare let gtag: any; // put this before the @Injectable decorator
...
// Below are functions of the analytics service
useGA(): boolean {
  return Boolean(
    environment.googleAnalyticsId &&
      environment.googleAnalyticsId.trim() !== '' &&
      environment.googleTagManagerId &&
      environment.googleTagManagerId.trim() !== '' &&
      typeof gtag !== 'undefined',
  );
}

loadBasicScripts() {
    if (!this.useGA()) return;
    const head = document.getElementsByTagName('head')[0];
    if (head !== null && head !== undefined) {
      const googleAnalyticsSrc = document.createElement('script');
      googleAnalyticsSrc.async = true;
      googleAnalyticsSrc.src = `https://www.googletagmanager.com/gtag/js?id=${environment.googleAnalyticsId}`;

      const googleAnalyticsScript = document.createElement('script');
      googleAnalyticsScript.type = 'text/javascript';
      googleAnalyticsScript.innerHTML = `
      window.dataLayer = window.dataLayer || [];
      function gtag() {
        dataLayer.push(arguments);
      }
      gtag('js', new Date());

      gtag('config', '${environment.googleAnalyticsId}');
    `;

      const googleTagManagerScript = document.createElement('script');
      googleTagManagerScript.type = 'text/javascript';

      googleTagManagerScript.innerHTML = ` (function (w, d, s, l, i) {
      w[l] = w[l] || [];
      w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
      var f = d.getElementsByTagName(s)[0],
        j = d.createElement(s),
        dl = l != 'dataLayer' ? '&l=' + l : '';
      j.async = true;
      j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
      f.parentNode.insertBefore(j, f);
    })(window, document, 'script', 'dataLayer', '${environment.googleTagManagerId}');
    `;

      document.head.appendChild(googleAnalyticsSrc);
      document.head.appendChild(googleAnalyticsScript);
      document.head.appendChild(googleTagManagerScript);
    }
    const body = document.getElementsByTagName('body')[0];
    if (body !== null && body !== undefined) {
      const googleAnalyticsTagNoScript = document.createElement('noscript');
      googleAnalyticsTagNoScript.innerHTML = `
      <iframe
        src="https://www.googletagmanager.com/ns.html?id=${environment.googleTagManagerId}"
        height="0"
        width="0"
        style="display: none; visibility: hidden"
      ></iframe>
    `;

      document.body.appendChild(googleAnalyticsTagNoScript);
    }
  }

// use the script loader in the app.component.ts:
ngOnInit(): void {
  this.analyticsService.loadBasicScripts();
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.