Angular 4+使用Google Analytics

Leo*_*ira 52 google-analytics typescript typescript-typings angular

我正在尝试使用角度为4的Google Analytics,但我在ts中找不到任何@type到ga.js.

为了快速解决方案,我在每个组件中使用了它:

declare let ga: any;
Run Code Online (Sandbox Code Playgroud)

按照我如何解决它:

创建一个动态加载GA的函数,将GA脚本与当前的trackingId和user一起插入.

    loadGA(userId) {
        if (!environment.GAtrackingId) return;

        let scriptId = 'google-analytics';

        if (document.getElementById(scriptId)) {
            return;
        }

        var s = document.createElement('script') as any;
        s.type = "text/javascript";
        s.id = scriptId;
        s.innerText = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', { trackingId: '" + **environment.GAtrackingId** + "', cookieDomain: 'auto', userId: '" + **userId** + "'});ga('send', 'pageview', '/');";

        document.getElementsByTagName("head")[0].appendChild(s);
    }
Run Code Online (Sandbox Code Playgroud)

创建服务以实现您需要的方法.

import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';

declare let ga: any;

@Injectable()
export class GAService {
    constructor() {
    }

    /**
     * Checks if the GA script was loaded.
     */
    private useGA() : boolean { 
        return environment.GAtrackingId && typeof ga !== undefined;
    }

    /**
     * Sends the page view to GA.
     * @param  {string} page The path portion of a URL. This value should start with a slash (/) character.
     */
    sendPageView(
        page: string
    ) {
        if (!this.useGA()) return;
        if (!page.startsWith('/')) page = `/${page}`;      
        ga('send', 'pageview', page);
    }


    /**
     * Sends the event to GA.
     * @param  {string} eventCategory Typically the object that was interacted with (e.g. 'Video')
     * @param  {string} eventAction The type of interaction (e.g. 'play')
     */
    sendEvent(
        eventCategory: string,
        eventAction: string
    ) { 
        if (!this.useGA()) return;
        ga('send', 'event', eventCategory, eventAction);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我最终使用组件中注入的服务.

constructor(private ga: GAService) {}

ngOnInit() { this.ga.sendPageView('/join'); }
Run Code Online (Sandbox Code Playgroud)

Lai*_*iso 83

首先,您需要在自己的网站上安装Google Analytics的输入法 devDependencies

npm install --save-dev @types/google.analytics
Run Code Online (Sandbox Code Playgroud)

然后在基础中添加跟踪代码index.html,并删除最后一行,如下所示:

<body>
  <app-root>Loading...</app-root>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-XXXXXX-ID', 'auto');  // <- add the UA-ID 
                                           // <- remove the last line 
  </script>
</body>
Run Code Online (Sandbox Code Playgroud)

下一步是更新主组件构造函数以进行事件跟踪.

constructor(public router: Router) {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        ga('set', 'page', event.urlAfterRedirects);
        ga('send', 'pageview');
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

如果要跟踪某些特定事件,还可以创建服务并将其注入要实现事件跟踪的任何组件.

// ./src/app/services/google-analytics-events-service.ts

import {Injectable} from "@angular/core";

@Injectable()
export class GoogleAnalyticsEventsService {

  public emitEvent(eventCategory: string,
                   eventAction: string,
                   eventLabel: string = null,
                   eventValue: number = null) {
    ga('send', 'event', { eventCategory, eventLabel, eventAction, eventValue });
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您想要跟踪主组件的单击,您需要做的就是注入GoogleAnalyticsEventsService并调用emitEvent()方法.

更新的主组件源代码:

constructor(public router: Router, public googleAnalyticsEventsService: GoogleAnalyticsEventsService) {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        ga('set', 'page', event.urlAfterRedirects);
        ga('send', 'pageview');
      }
    });
  }
  submitEvent() { // event fired from home.component.html element (button, link, ... )
    this.googleAnalyticsEventsService.emitEvent("testCategory", "testAction", "testLabel", 10);
  }
Run Code Online (Sandbox Code Playgroud)

  • 不应该`npm install --save-dev @ types/google.analytics`修复`declare var ga:Function;`的需要吗? (6认同)
  • 尝试在组件中添加声明:`declare var ga:Function;` (5认同)
  • 我通过添加一个import语句解决了ReferenceError:`@corts/google.analytics'中的`import {};` (4认同)
  • 在Angular 4中,我得到了他的错误"找不到名字'ga'.webpack:无法在终端中编译此代码`if(event instanceof NavigationEnd){ga('set','page',event.urlAfterRedirects); ga('发送','网页浏览'); }` (2认同)
  • 关于参考错误,您可以尝试从我的“ tsconfig.json”文件中删除空的“ types”数组,该文件对我有用。从文档中:https://www.typescriptlang.org/docs/handbook/tsconfig-json.html``指定“类型”:[]禁用自动包含@types包。因此,删除空数组意味着全局@types包中的声明将自动包含在内,而无需专门将它们导入任何文件中。 (2认同)

Dzh*_*eyt 28

令我惊讶的是,这里没有人提到Google的标记管理器(这是过去几年中每当我添加新身份时Google Analytics(分析)控制台为我输出的脚本版本)。

这是我今天想到的一个解决方案,它是其他答案中已经提到的解决方案的一种变体,它是Google跟踪代码管理器脚本的适配器。我认为这对于从迁移ga()到的人很有用gtag()(据我所知,建议进行迁移)。

analytics.service.ts

declare var gtag: Function;

@Injectable({
  providedIn: 'root'
})
export class AnalyticsService {

  constructor(private router: Router) {

  }

  public event(eventName: string, params: {}) {
    gtag('event', eventName, params);
  }

  public init() {
    this.listenForRouteChanges();

    try {

      const script1 = document.createElement('script');
      script1.async = true;
      script1.src = 'https://www.googletagmanager.com/gtag/js?id=' + environment.googleAnalyticsKey;
      document.head.appendChild(script1);

      const script2 = document.createElement('script');
      script2.innerHTML = `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', '` + environment.googleAnalyticsKey + `', {'send_page_view': false});
      `;
      document.head.appendChild(script2);
    } catch (ex) {
      console.error('Error appending google analytics');
      console.error(ex);
    }
  }

  private listenForRouteChanges() {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        gtag('config', environment.googleAnalyticsKey, {
          'page_path': event.urlAfterRedirects,
        });
        console.log('Sending Google Analytics hit for route', event.urlAfterRedirects);
        console.log('Property ID', environment.googleAnalyticsKey);
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

先决条件:

  • 在的imports []部分中声明服务app.module.ts
  • 在您的app.component.ts(或任何更高级别的组件<router-outlet>在其模板中包含标记)中,注入AnalyticsService并this.analytics.init()尽早调用(例如ngOnInit)
  • 在environment.ts中(以我的情况为-environment.prod.ts),将Analytics ID添加为 googleAnalyticsKey: 'UA-XXXXXXX-XXXX'

  • 感谢这个解决方案。不过有 1 个小错误。服务声明需要进行如下更改。在“app.module.ts”的“providers[]”部分中声明该服务。 (2认同)
  • @Shabith实际上是[推荐的做法,在模块中取代了[providers:[]],这是从Angular 6+开始的推荐做法](https://medium.com/@tomastrajan/total-guide-to-angular-6-依赖关系注入-providedin-vs-providers-85b7a347b59f)。就个人而言,我仍然更喜欢“提供者”方法的“清洁性”,但是谁问我。:) (2认同)

Art*_*xel 20

使用环境变量,异步方式加载谷歌分析;

(适用于Angular 5)

(使用@Laiso回答)

谷歌,analytics.service.ts

import {Injectable} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
declare var ga: Function;

@Injectable()
export class GoogleAnalyticsService {

  constructor(public router: Router) {
    this.router.events.subscribe(event => {
      try {
        if (typeof ga === 'function') {
          if (event instanceof NavigationEnd) {
            ga('set', 'page', event.urlAfterRedirects);
            ga('send', 'pageview');
            console.log('%%% Google Analytics page view event %%%');
          }
        }
      } catch (e) {
        console.log(e);
      }
    });

  }


  /**
   * Emit google analytics event
   * Fire event example:
   * this.emitEvent("testCategory", "testAction", "testLabel", 10);
   * @param {string} eventCategory
   * @param {string} eventAction
   * @param {string} eventLabel
   * @param {number} eventValue
   */
  public emitEvent(eventCategory: string,
   eventAction: string,
   eventLabel: string = null,
   eventValue: number = null) {
    if (typeof ga === 'function') {
      ga('send', 'event', {
        eventCategory: eventCategory,
        eventLabel: eventLabel,
        eventAction: eventAction,
        eventValue: eventValue
      });
    }
  }


}
Run Code Online (Sandbox Code Playgroud)

在app.component内部或任何组件:

 // ... import stuff

 import { environment } from '../../../environments/environment';

 // ... declarations

 constructor(private googleAnalyticsService: GoogleAnalyticsService){
    this.appendGaTrackingCode();
 }

 private appendGaTrackingCode() {
    try {
      const script = document.createElement('script');
      script.innerHTML = `
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

        ga('create', '` + environment.googleAnalyticsKey + `', 'auto');
      `;
      document.head.appendChild(script);
    } catch (ex) {
     console.error('Error appending google analytics');
     console.error(ex);
    }
  }

// Somewhere else we can emit a new ga event
this.googleAnalyticsService.emitEvent("testCategory", "testAction", "testLabel", 10);
Run Code Online (Sandbox Code Playgroud)

  • google-analytics.service.ts是一个很好的解决方案,但请注意将appendGaTrackingCode()从推荐的index.html <head>移动到app.component的一个缺点意味着谷歌分析将无法准确测量平均页面加载时间因为只有在检索并执行角度javascript包之后它才会启动计时器. (2认同)

Fil*_*cik 7

GoogleAnalyticsService

您可以创建service订阅路由器事件并将其注入,app.module.ts这样您就不必在每个组件中注入它.

@Injectable()
export class GoogleAnalyticsService {

  constructor(router: Router) {
    if (!environment.production) return; // <-- If you want to enable GA only in production
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        ga('set', 'page', event.url);
        ga('send', 'pageview');
      }
    })
  }
Run Code Online (Sandbox Code Playgroud)

这是教程(我的博客).


小智 5

为了避免在窗口级别全局定义 ga 时进行任何类型检查,那么您可以简单地执行

 window["ga"]('send', {
    hitType: 'event',
    eventCategory: 'eventCategory',
    eventAction: 'eventAction'
    });
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。