J'essaie d'utiliser Google Analytics avec angular 4, mais je ne trouve aucun type @ dans ga.js dans ts.
Pour une solution rapide, j'ai utilisé cela dans chaque composant:
declare let ga: any;
Après avoir résolu le problème:
Créez une fonction pour charger le GA de manière dynamique, qui insère le script GA avec le trackingId et l'utilisateur actuels.
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);
}
Créez le service pour implémenter les méthodes dont vous aurez besoin.
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);
}
}
Ensuite, j'ai finalement utilisé le service injecté dans le composant.
constructor(private ga: GAService) {}
ngOnInit() { this.ga.sendPageView('/join'); }
Tout d’abord, vous devez installer des saisies pour Google Analytics dans votre devDependencies
npm install --save-dev @types/google.analytics
Ajoutez ensuite votre code de suivi dans la base index.html
et supprimez la dernière ligne comme indiqué ci-dessous:
<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>
L'étape suivante consiste à mettre à jour le constructeur de votre composant home pour le suivi des événements.
constructor(public router: Router) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
ga('set', 'page', event.urlAfterRedirects);
ga('send', 'pageview');
}
});
}
Si vous souhaitez suivre un événement spécifique, vous pouvez également créer un service et l'injecter dans tout composant pour lequel vous souhaitez implémenter le suivi des événements.
// ./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 });
}
}
Donc, si vous voulez suivre un clic sur votre composant home par exemple, tout ce que vous avez à faire est d’injecter la méthode GoogleAnalyticsEventsService
et d’appeler la méthode emitEvent()
.
Le code source du composant home mis à jour:
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);
}
Je suis surpris que personne n'ait mentionné le gestionnaire de balises de Google pour le moment (qui est la version du script que la console Google Analytics génère pour moi ces dernières années. , chaque fois que j'ajoute une nouvelle identité).
Voici une solution que j'ai proposée aujourd'hui, qui est une variante des solutions déjà mentionnées dans les autres réponses, un adaptateur pour le script Tag Manager de Google. Je pense que cela serait utile pour les personnes ayant migré de ga()
à gtag()
(une migration qui est recommandée à ma connaissance).
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);
}
});
}
}
Conditions préalables:
app.module.ts
.<router-outlet>
dans son modèle), injectez AnalyticsService et appelez this.analytics.init()
dès que possible (par exemple, ngOnInit).googleAnalyticsKey: 'UA-XXXXXXX-XXXX'
(Fonctionne sur Angular 5)
(Utilisation de @Laiso answer)
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
});
}
}
}
// ... 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);
Vous pouvez créer service
qui souscrit aux événements de routeur et l'injecter dans app.module.ts
afin que vous n'ayez pas à l'injecter dans chaque composant.
@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');
}
})
}
Pour éviter toute vérification de type si ga est défini globalement au niveau de la fenêtre, vous pouvez simplement le faire.
window["ga"]('send', {
hitType: 'event',
eventCategory: 'eventCategory',
eventAction: 'eventAction'
});
J'espère que ça aide.
Personnellement, j'ai trouvé cela assez simple, tout simplement:
<app-root>
dans index.html (comme indiqué ci-dessus)Dans mon app.component.ts
j'ai ajouté ceci:
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));
}
}
Ce n'est pas très différent de ce qui précède, mais le rend beaucoup plus facile pour les tests.
Je suggère d’incorporer le script Segment dans votre index.html
et d’étendre la bibliothèque d’analyses sur l’objet window
:
declare global {
interface Window { analytics: any; }
}
Ajoutez ensuite les appels de suivi au gestionnaire d’événements (click)
:
@Component({
selector: 'app-signup-btn',
template: `
<button (click)="trackEvent()">
Signup with Segment today!
</button>
`
})
export class SignupButtonComponent {
trackEvent() {
window.analytics.track('User Signup');
}
}
Je suis le responsable de https://github.com/segmentio/analytics-angular . Je vous recommande de vérifier si vous souhaitez résoudre ce problème en utilisant une API unique pour gérer les données de vos clients et pouvoir l'intégrer à tout autre outil d'analyse (nous prenons en charge plus de 250 destinations), sans écrire de code supplémentaire. ????