Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Dynamically loading Google Analytics?

I'm using Google Analytics Global site tag (gtag.js)

However, I can't directly insert the tag in index.html because the trackingID is dynamically loaded over network, so I need to wait to get the trackingID before loading Google Analytics.

For this, I created a service.

@Injectable()
export class HelpersService {

  constructor() {}

  static loadGoogleAnalytics(trackingID: string): void {
    document.write('' +
      '<script async src=\'https://www.googletagmanager.com/gtag/js?id=' + trackingID + '\'></script>\n' +
      '  <script>\n' +
      '    window.dataLayer = window.dataLayer || [];\n' +
      '\n' +
      '    function gtag() {\n' +
      '      dataLayer.push(arguments)\n' +
      '    };\n' +
      '    gtag(\'js\', new Date());\n' +
      '\n' +
      '    gtag(\'config\', \'' + trackingID + '\');\n' +
      '  </script>');
  }
}

Then, once I get my GA tracking ID set, in my root component, I call this method:

HelpersService.loadGoogleAnalytics(myGATrackingID);

The issue

GA is loaded and works (I can see my user is detected in GA dashboard). But my Angular project is not loaded at all, I have a blank page, infinite loading, and inspecting HTML shows me GA code only, not my Angular project.

Any idea?

like image 359
David D. Avatar asked Mar 11 '19 11:03

David D.


1 Answers

Using document.write() after an HTML document is fully loaded, will delete all existing HTML: example here

In your case, I would simply extract the function from the <script> tag as a definition, or if you strictly need to load this after the app has started, extract it to a lazy-loaded angular module.

EDIT -> here is a code sample:

  static loadGoogleAnalytics(trackingID: string): void {

    let gaScript = document.createElement('script');
    gaScript.setAttribute('async', 'true');
    gaScript.setAttribute('src', `https://www.googletagmanager.com/gtag/js?id=${ trackingID }`);

    let gaScript2 = document.createElement('script');
    gaScript2.innerText = `window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag(\'js\', new Date());gtag(\'config\', \'${ trackingID }\');`;

    document.documentElement.firstChild.appendChild(gaScript);
    document.documentElement.firstChild.appendChild(gaScript2);
  }
like image 72
ForestG Avatar answered Oct 04 '22 06:10

ForestG