Javascript 在 Angular2 中跟踪 Google Analytics 页面浏览量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37655898/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tracking Google Analytics Page Views in Angular2
提问by Ian Belcher
I have built a new site using Angular 2 as the front-end. As everything is done via push state, there are no page loads which typically trigger the Google Analytics code to send a page view to Google's servers.
我使用 Angular 2 作为前端构建了一个新站点。由于一切都是通过推送状态完成的,因此没有页面加载通常会触发 Google Analytics 代码将页面视图发送到 Google 的服务器。
How can I manually send page view events to Google so that I can track what users of my site are viewing?
如何手动向 Google 发送页面查看事件,以便跟踪我网站的用户正在查看的内容?
回答by Ian Belcher
I managed to get this working by subscribing to changes on the router, checking that the route had actually changed (I was getting multiple events on some routes at times) and then sending the new path to Google.
我通过订阅路由器上的更改,检查路由是否实际更改(我有时在某些路由上收到多个事件),然后将新路径发送到 Google,设法使其工作。
app.component.ts
app.component.ts
import { ... } from '...';
// Declare ga function as ambient
declare var ga:Function;
@Component({ ... })
export class AppComponent {
private currentRoute:string;
constructor(_router:Router) {
// Using Rx's built in `distinctUntilChanged ` feature to handle url change c/o @dloomb's answer
router.events.distinctUntilChanged((previous: any, current: any) => {
// Subscribe to any `NavigationEnd` events where the url has changed
if(current instanceof NavigationEnd) {
return previous.url === current.url;
}
return true;
}).subscribe((x: any) => {
ga('set', 'page', x.url);
ga('send', 'pageview')
});
}
}
}
You also need to include the google analytics code in your main index file before loading your angular2 app so that the global ga
object exists, but you don't want to send the initial view twice. In order to do this, remove the following line from the GA script
在加载 angular2 应用程序之前,您还需要在主索引文件中包含 google 分析代码,以便全局ga
对象存在,但您不想发送两次初始视图。为此,请从 GA 脚本中删除以下行
index.html
索引.html
<script>
(function(i,s,o,g,r,a,m){...})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'auto');
// Remove this line to avoid sending the first page view twice.
//ga('send', 'pageview');
</script>
<!--
Load your ng2 app after ga.
This style of deferred script loading doesn't guarantee this will happen
but you can use Promise's or what works for your particular project.
-->
<script defer type="text/javascript" src="/app.js"></script>
Using a third party library
使用第三方库
As an alternative to implementing GA yourself, the library Angulartics2is also a popular tool for implementing GA tracking and also integrates with other analytics vendors as well.
作为自己实施 GA 的替代方案,库Angulartics2也是实施 GA 跟踪的流行工具,并且还与其他分析供应商集成。
回答by dloomb
Expanding on Ian's answer. You can use Rx's built in features to handle the distinction between current and new routes.
扩展伊恩的回答。您可以使用 Rx 的内置功能来处理当前路由和新路由之间的区别。
import { NavigationEnd, Router } from '@angular/router';
declare var ga: any;
export class AppComponent {
constructor(public router: Router) {
router.events.distinctUntilChanged((previous: any, current: any) => {
if(current instanceof NavigationEnd) {
return previous.url === current.url;
}
return true;
}).subscribe((x: any) => {
console.log('router.change', x);
ga('send', 'pageview', x.url);
});
}
}
We are using the distinctUntilChanged operator to make the observer only emit items that are of type NavigationEnd and do not have the same route as the previously emitted item.
我们使用 distinctUntilChanged 操作符让观察者只发出 NavigationEnd 类型的项目,并且与之前发出的项目没有相同的路线。
回答by nyxz
If you are running into this issue after August 2017then you most probably should use gtag.js(Google Universal Analytics Global Site Tag) instead of the old analytics.js. I suggest you to check the difference between the both in Migrate from analytics.js to gtag.jspage, as well as How gtag.js works in Single page applicationsbefore continuing.
如果您在 2017 年 8 月之后遇到这个问题,那么您很可能应该使用gtag.js(Google Universal Analytics Global Site Tag)而不是旧的analytics.js。我建议您在继续之前检查从 analytics.js 迁移到 gtag.js页面中的两者之间的区别,以及gtag.js 在单页面应用程序中的工作原理。
When you get your code snippet from Google Analytics it looks like this:
当您从 Google Analytics 获取代码片段时,它看起来像这样:
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= GOOGLE_ANALYTICS_ID %>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<%= GOOGLE_ANALYTICS_ID %>'); <!-- Remove that one -->
</script>
You need to remove the last line of the script and add the rest to your index.html
.
您需要删除脚本的最后一行并将其余部分添加到您的index.html
.
Then you have to add the line you deleted from the script above to your code and add the page to track. Basically it's almost the same as the guys above suggested for analytics.js
but now you use the gtag.js
function.
然后,您必须将从上述脚本中删除的行添加到您的代码中,并将页面添加到 track。基本上它与上面建议的人几乎相同,analytics.js
但现在您使用该gtag.js
功能。
For example if you want to track all pages you open here is the sample code:
例如,如果您想跟踪您在此处打开的所有页面,示例代码是:
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import 'rxjs/add/operator/distinctUntilChanged';
// This still has to be declared
declare var gtag: Function;
@Component({
moduleId: module.id,
selector: 'my-app',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
})
export class AppComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
this.router.events.distinctUntilChanged((previous: any, current: any) => {
// Subscribe to any `NavigationEnd` events where the url has changed
if(current instanceof NavigationEnd) {
return previous.url === current.url;
}
return true;
}).subscribe((x: any) => {
gtag('config', '<%= GOOGLE_ANALYTICS_ID %>', {'page_path': x.url});
});
}
}
If you've read the documentation for the gtag.js
then you know that there could be tons of tracking options, but I focus on the most basic usage here.
如果您阅读了 的文档,gtag.js
那么您就会知道可能有大量的跟踪选项,但我在这里专注于最基本的用法。
回答by Cyril Blanchet
In Angular 6, I suggest for the app.component.ts:
在 Angular 6 中,我建议使用 app.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router'
import { Title } from '@angular/platform-browser';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(
private router: Router,
private titleService: Title
){ }
ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
(<any>window).gtag('config', '<%= GOOGLE_ANALYTICS_ID %>', {
'page_title' : this.titleService.getTitle(),
'page_path': event.urlAfterRedirects
});
}
});
}
}
For the index.html :
对于 index.html :
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= GOOGLE_ANALYTICS_ID %>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
</script>
You could manage the title of your pages with the Title service provided by Angular : https://angular.io/guide/set-document-title
您可以使用 Angular 提供的 Title 服务来管理页面的标题:https: //angular.io/guide/set-document-title
回答by Omer Gurarslan
Assuming that every Angular Route has its own title in app.routing.ts
:
假设每个 Angular Route 在 中都有自己的标题app.routing.ts
:
{
path: 'shop',
component: ShopComponent,
data: {
title: ' == This is Shop Component Title =='
},
canActivate: [AuthGuard]
},
Previously mentioned solutions will still display the same page title for each route on Google Analytics Report. In order to make use of corresponding Angular Route titles ( instead of index.html <title>
tag content all the time), use the code below in app.component.ts
之前提到的解决方案仍会在 Google Analytics 报告中为每条路线显示相同的页面标题。为了利用相应的Angular Route标题(而不是一直使用index.html<title>
标签内容),使用下面的代码app.component.ts
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
(<any>window).ga('set', 'page', event.urlAfterRedirects);
// ----------
//use the following 3 lines of code to use
//correnct titles for routes
// ----------
let currentRoute = this.route.root;
let title = this.getPageTitle(currentRoute);
(<any>window).ga('set', 'title', title);
(<any>window).ga('send', 'pageview');
}
});
...where getPageTitle
method is as follows:
...其中getPageTitle
方法如下:
getPageTitle = function (currentRoute: ActivatedRoute) {
let data;
do {
const childrenRoutes = currentRoute.children;
currentRoute = null;
childrenRoutes.forEach(route => {
if (route.outlet === 'primary') {
currentRoute = route;
data = route.snapshot.data;
}
});
} while (currentRoute);
return data.title;
};
Note: This solution applies to Anguler 5 and below. In Angular 6, you can also use TitleService
注意:此解决方案适用于 Anguler 5 及以下版本。在 Angular 6 中,您还可以使用TitleService
回答by Tony Muchui Blaxx
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
ga('set','page', event.urlAfterRedirects);
ga('send', 'pageview');
}
});