Suivi des pages vues sur Google Analytics en Angular2

j'ai construit un nouveau site en utilisant L'angle 2 comme frontal. Comme tout est fait via push state, il n'y a pas de chargement de page qui déclenche typiquement le code Google Analytics pour envoyer une vue de page aux serveurs de Google.

Comment puis-je envoyer manuellement des événements de vue de page à Google afin que je puisse suivre ce que les utilisateurs de mon site sont en train de regarder?

37
demandé sur Ian Belcher 2016-06-06 14:10:28

5 réponses

j'ai réussi à obtenir ce fonctionnement en m'abonnant à des modifications sur le routeur, en vérifiant que la route avait effectivement changé (je recevais plusieurs événements sur certaines routes à certains moments) et puis en envoyant le nouveau chemin à Google.

app.composant.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')
        });
      }
    }
}

vous devez également inclure le code Google analytics dans votre fichier index principal avant de charger votre application angular2 afin que lega objet existe, mais vous ne voulez pas envoyer la vue initiale à deux reprises. Pour ce faire, supprimez la ligne suivante du script GA

index.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>

utilisation d'une bibliothèque tierce

comme alternative à l'implémentation de GA vous-même, la bibliothèque Angulartics2 est également un outil populaire pour la mise en œuvre de GA suivi et s'intègre également avec d'autres fournisseurs d'analyse.

50
répondu Ian Belcher 2017-03-17 01:08:20

développer la réponse de Ian. Vous pouvez utiliser les fonctionnalités intégrées de Rx pour gérer la distinction entre les routes actuelles et nouvelles.

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);
            });
        }
    }

nous utilisons l'opérateur distinctUntilChanged pour que l'observateur n'émette que des éléments de type NavigationEnd qui n'ont pas la même route que l'élément émis précédemment.

33
répondu dloomb 2016-09-21 17:21:55

Si vous rencontrez ce problème après le mois d'août 2017 alors vous devriez probablement utiliser gtag.js (Google Universal Analytics Global Site Tag) au lieu de l'ancienne google analytics.js. Je vous suggère de vérifier la différence entre les deux dans migrer à partir de l'analyse.js à gtag.js page, ainsi que Comment gtag.js fonctionne en Single page applications avant de continuer.

quand vous obtenez votre code snippet de Google Analytics il ressemble à ceci:

<!-- 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>

vous devez supprimer la dernière ligne du script et ajouter le reste à votre index.html.

alors vous devez ajouter la ligne que vous avez supprimée du script ci-dessus à votre code et ajouter la page à suivre. Fondamentalement, il est presque le même que les gars ci-dessus suggéré pour analytics.js mais maintenant, vous utilisez le gtag.js fonction.

Par exemple, si vous souhaitez suivre toutes les pages que vous ouvrez voici l'exemple de 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});
        });
    }
}

si vous avez lu la documentation pour le gtag.js alors vous savez qu'il pourrait y avoir des tonnes d'options de suivi, mais je me concentre sur l'utilisation la plus élémentaire ici.

13
répondu nyxz 2017-12-05 16:33:36

dans L'angle 6, je suggère pour l'application.composant.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
        });
      }
    });
  }

}

Pour l'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>
https://angular.io/guide/set-document-title

1
répondu Cyril Blanchet 2018-08-28 15:22:28

en supposant que chaque Route angulaire a son propre titre en app.routing.ts:

   {
    path: 'shop',
    component: ShopComponent,
    data: {
      title: ' == This is Shop Component Title =='
    },
    canActivate: [AuthGuard]
  },

les solutions mentionnées précédemment afficheront toujours le même titre de page pour chaque route sur le rapport Google Analytics. Afin d'utiliser les titres de Route angulaires correspondants ( au lieu d'index.html <title> le contenu de la balise tout le temps), utilisez le code ci-dessous dans 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');

  }
});

...où getPageTitle la méthode est la suivante:

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: Cette solution s'applique à Anguler 5 et ci-dessous. Dans L'angle 6, Vous pouvez aussi utiliser TitleService

0
répondu Omer Gurarslan 2018-08-31 17:39:38