Angular 4+ с помощью Google Analytics
Я пытаюсь использовать Google Analytics с angular 4, но я не могу найти какой-либо @type для ga.js в ts.
Для быстрого решения я использовал это в каждом компоненте:
declare let ga: any;
После этого я решил:
Создайте функцию для динамической загрузки GA, которая вставляет GA script с текущим идентификатором отслеживания и пользователем.
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);
}
Создайте службу для реализации методов, которые вам понадобятся.
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);
}
}
Затем я, наконец, использую службу, инъецированную в компонент.
constructor(private ga: GAService) {}
ngOnInit() { this.ga.sendPageView('/join'); }
Ответы
Ответ 1
Прежде всего, вам нужно установить наборы для Google Analytics в ваших devDependencies
npm install --save-dev @types/google.analytics
Затем добавьте свой код отслеживания в базовый 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>
Следующий шаг состоит в том, чтобы обновить конструктор домашних компонентов для отслеживания событий.
constructor(public router: Router) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
ga('set', 'page', event.urlAfterRedirects);
ga('send', 'pageview');
}
});
}
Если вы хотите отслеживать какое-то конкретное событие, вы также можете создать сервис и внедрить его в любой компонент, для которого вы хотите реализовать отслеживание событий.
// ./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 });
}
}
Поэтому, если вы хотите отследить клик по вашему домашнему компоненту, например, все, что вам нужно сделать, это внедрить 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);
}
Ответ 2
Загрузите аналитику google, используя среду vars, асинхронный путь;
(Работает на Angular 5)
(с использованием ответа @Laiso)
Google-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
});
}
}
}
Внутри 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);
Ответ 3
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');
}
})
}
Вот учебник (мой блог).
Ответ 4
Я удивлен, что никто здесь не упомянул Google Tag Manager (это версия скрипта, которую консоль Google Analytics выводит для меня в течение последних нескольких лет всякий раз, когда я добавляю новую личность).
Вот решение, которое я придумал сегодня, - это вариант решений, уже упомянутых в других ответах, адаптера к скрипту Google Tag Manager. Я думаю, что это было бы полезно для людей, которые мигрировали из 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);
}
});
}
}
Предпосылки:
- Объявите службу в разделе
app.module.ts
[] вашего app.module.ts
. - В вашем app.component.ts (или любом другом компоненте более высокого уровня, содержащем
<router-outlet>
в своем шаблоне), this.analytics.init()
AnalyticsService и вызовите this.analytics.init()
как можно раньше (например, ngOnInit) - В environment.ts (в моем случае - environment.prod.ts) добавьте идентификатор
googleAnalyticsKey: 'UA-XXXXXXX-XXXX'
Analytics в виде googleAnalyticsKey: 'UA-XXXXXXX-XXXX'
Ответ 5
Лично я нашел это довольно просто просто:
- Добавление кода отслеживания GA после моего
<app-root>
в index.html (как показано выше) - Включение Angulartics для GA в мое приложение (пример GA здесь)
В моем app.component.ts
я добавил это:
import {Component, OnInit} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
import {Angulartics2GoogleAnalytics} from 'angulartics2/ga';
import {filter} from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private ga: Angulartics2GoogleAnalytics,
private router: Router) {
}
ngOnInit() {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) =>
this.ga.pageTrack(event.urlAfterRedirects));
}
}
Это не сильно отличается от вышеупомянутого, но делает его намного проще для тестирования.
Ответ 6
Чтобы избежать проверки любого типа, если ga определено глобально на уровне окна, вы можете просто сделать
window["ga"]('send', {
hitType: 'event',
eventCategory: 'eventCategory',
eventAction: 'eventAction'
});
Надеюсь, что это поможет.
Ответ 7
Я предлагаю встроить скрипт Segment в ваш index.html
и расширить библиотеку аналитики на объект window
:
declare global {
interface Window { analytics: any; }
}
Затем добавьте отслеживание вызовов в обработчик событий (click)
:
@Component({
selector: 'app-signup-btn',
template: '
<button (click)="trackEvent()">
Signup with Segment today!
</button>
'
})
export class SignupButtonComponent {
trackEvent() {
window.analytics.track('User Signup');
}
}
Я поддерживаю https://github.com/segmentio/analytics-angular. Я рекомендую проверить это, если вы хотите решить эту проблему с помощью единственного API для управления данными ваших клиентов и иметь возможность интеграции с любым другим аналитическим инструментом (мы поддерживаем более 250+ адресатов) - без написания какого-либо дополнительного кода. 🙂