Suivi des vues de page Google Analytics avec AngularJS

221

J'installe une nouvelle application utilisant AngularJS comme interface. Tout côté client se fait avec pushstate HTML5 et j'aimerais pouvoir suivre mes pages vues dans Google Analytics.

dj2
la source
Essayez les angulartiques luisfarzati.github.io/angulartics
David
2
les angulartiques sont dépréciés. Utilisez angular-google-analytics
webdev5
5
@ webdev5 Une nouvelle version d'angulartics est sortie. Essayez-le sur: angulartics.github.io
Devner

Réponses:

240

Si vous utilisez ng-viewdans votre application Angular, vous pouvez écouter l' $viewContentLoadedévénement et envoyer un événement de suivi à Google Analytics.

En supposant que vous avez configuré votre code de suivi dans votre fichier index.html principal avec un nom var _gaqet MyCtrl est ce que vous avez défini dans la ng-controllerdirective.

function MyCtrl($scope, $location, $window) {
  $scope.$on('$viewContentLoaded', function(event) {
    $window._gaq.push(['_trackPageView', $location.url()]);
  });
}

MISE À JOUR: pour une nouvelle version de google-analytics, utilisez celle-ci

function MyCtrl($scope, $location, $window) {
  $scope.$on('$viewContentLoaded', function(event) {
    $window.ga('send', 'pageview', { page: $location.url() });
  });
}
dj2
la source
12
FWIW ça devrait être _trackPageviewet non _trackPageView... passé 10 minutes à se gratter la tête :)
sajal
123
J'utiliserais $rootScope.$on('$routeChangeSuccess', ...)
bearfriend
5
@DavidRivers Hm, ça fait un moment, mais rien qu'en regardant cette réponse et mon commentaire, il semblerait que l'appliquer à $rootScopegarantirait qu'il ne sera pas supprimé par un autre événement ou changement de DOM, et l'utilisation routeChangeSuccessse déclenchera à chaque fois que le la barre d'emplacement change, au lieu de changer de modèle de source de vue. Cela a-t-il du sens?
bearfriend
5
@ dg988 lors d'un événement $ routeChangeSuccess, vous ne pouvez PAS connaître à l'avance le titre de la page (qui, par exemple, pourrait être défini dans un contrôleur après qu'il a fini de traiter les données d'un service RESTful). De cette façon, seul avec l'URL de la page, Google Analytics suivra le titre de la page précédente.
Konstantin Tarkus
43
Si vous utilisez le nouveau script GA, c'est à la $window.ga('send', 'pageview', { page: $location.path() });place de la $window._gaq...partie. En outre, vous souhaiterez peut-être supprimer ga('send', 'pageview');de votre code GA d'origine pour éviter les doublons lorsque vous atterrissez pour la première fois sur une page.
CWSpear
57

Lorsqu'une nouvelle vue est chargée AngularJS, Google Analytics ne la considère pas comme un nouveau chargement de page. Heureusement, il existe un moyen de dire manuellement à GA d'enregistrer une URL en tant que nouvelle page vue.

_gaq.push(['_trackPageview', '<url>']); ferait le travail, mais comment lier cela avec AngularJS?

Voici un service que vous pourriez utiliser:

(function(angular) { 

  angular.module('analytics', ['ng']).service('analytics', [
    '$rootScope', '$window', '$location', function($rootScope, $window, $location) {
      var track = function() {
        $window._gaq.push(['_trackPageview', $location.path()]);
      };
      $rootScope.$on('$viewContentLoaded', track);
    }
  ]);

}(window.angular));

Lorsque vous définissez votre module angulaire, incluez le module d'analyse comme suit:

angular.module('myappname', ['analytics']);

MISE À JOUR :

Vous devez utiliser le nouveau code de suivi universel Google Analytics avec:

$window.ga('send', 'pageview', {page: $location.url()});
Haralan Dobrev
la source
6
L'autre chose à noter ici est que vous devez inclure le service "analytique" quelque part. J'ai fait le mien dans app.run.
Nix
Serait-ce nécessaire d'inclure dans chaque module, ou tout simplement l'application initiale?
designermonkey
2
@Designermonkey Cela devrait fonctionner si vous incluez uniquement dans votre module d'application principal. Si vous avez un module totalement indépendant qui ne nécessite pas votre module principal, vous devrez peut-être l'inclure à nouveau. À votre santé!
Haralan Dobrev
Si vous utilisez un service, vous devez définir vos fonctions avec le mot-clé "this": source . Par exemple, dans le service , il serait this.track = function($window.ga('send', 'pageview', {page: $location.url()});Cela vous permettra d'utiliser au googleAnalytics.track();sein de votre app.run () fonction
zcoon
48
app.run(function ($rootScope, $location) {
    $rootScope.$on('$routeChangeSuccess', function(){
        ga('send', 'pageview', $location.path());
    });
});
dpineda
la source
8
Remarque: Si vous utilisez la minimisation / compilation, vous devez spécifier les noms des paramètres:app.run(["$rootScope", "$location", function(...
dplass
Cette solution est excellente si vous ne souhaitez pas inclure de code GA dans chaque contrôleur.
breez
1
Pas génial si vous avez du code asynchrone qui change dynamiquement votre titre, sinon c'est génial.
Johan
40

Juste un ajout rapide. Si vous utilisez le nouveau analytics.js, alors:

var track = function() {     
 ga('send', 'pageview', {'page': $location.path()});                
};

De plus, une astuce est que google analytics ne se déclenchera pas sur localhost. Donc, si vous testez sur localhost, utilisez ce qui suit au lieu de la création par défaut ( documentation complète )

ga('create', 'UA-XXXX-Y', {'cookieDomain': 'none'});
wynnwu
la source
Oh mec, merci. J'obtenais des erreurs étranges et j'ai remarqué que mon extrait de code ne contenait même pas de _gaq, hehe. Silly Google: mettre à jour leur code et tout ça! Haha.
CWSpear
3
Assurez-vous que vous utilisez $windowpour accéder à la fenêtre ( gaseul à l'intérieur d'Angular est très susceptible de l'être undefined). En outre, vous souhaiterez peut-être supprimer ga('send', 'pageview');de votre code GA d'origine pour éviter les doublons lorsque vous atterrissez pour la première fois sur une page.
CWSpear
6
En utilisant ui-router, vous pouvez envoyer des pages vues comme ceci:$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { ga('send', 'pageview', { 'page': $location.path(), 'title': toState.name }); });
pherris
2
Pour ajouter: Si vous utilisez des paramètres de recherche dans votre application, vous pouvez suivre ceux qui utilisent$location.url()
Ade
2
J'ai voté pour cette réponse car l'utilisation de .path () est meilleure que .url () car vous voulez normalement exclure les paramètres de chaîne de requête. Voir: Erreur de configuration Google Analytics # 2: Variables de chaîne de requête
frodo2975
11

J'ai créé un service + filtre qui pourrait vous aider, et peut-être aussi avec d'autres fournisseurs si vous choisissez de les ajouter à l'avenir.

Consultez https://github.com/mgonto/angularytics et faites-moi savoir comment cela fonctionne pour vous.

mgonto
la source
10

La fusion des réponses de wynnwu et dpineda a été ce qui a fonctionné pour moi.

angular.module('app', [])
  .run(['$rootScope', '$location', '$window',
    function($rootScope, $location, $window) {
      $rootScope.$on('$routeChangeSuccess',
        function(event) {
          if (!$window.ga) {
            return;
          }
          $window.ga('send', 'pageview', {
            page: $location.path()
          });
        });
    }
  ]);

Définir le troisième paramètre en tant qu'objet (au lieu de simplement $ location.path ()) et utiliser $ routeChangeSuccess au lieu de $ stateChangeSuccess a fait l'affaire.

J'espère que cela t'aides.

Pedro Lopez
la source
7

J'ai créé un exemple simple sur github en utilisant l'approche ci-dessus.

https://github.com/isamuelson/angularjs-googleanalytics

IBootstrap
la source
J'ai ajouté un correctif pour mieux signaler le chemin. alors maintenant, si vous avez la route du /account/:accountId chemin aka, http://somesite.com/account/123il signalera maintenant le chemin comme/account?accountId=123
IBootstrap
@IBootstrap quel est l'avantage de mettre les paramètres de route dans la chaîne de requête?
Pavel Nikolov
@IBootstrap J'ai la même question, quel est l'avantage de mettre les paramètres de route dans la chaîne de requête?
Dzung Nguyen
1
Toutes les routes ne sont pas des pages différentes et GA traite chaque route comme une page différente. En convertissant l'itinéraire en chaîne de requête, vous avez la possibilité d'ignorer des parties de la chaîne de requête.
IBootstrap
5

La meilleure façon de procéder consiste à utiliser Google Tag Manager pour déclencher vos balises Google Analytics en fonction des écouteurs d'historique. Ceux-ci sont intégrés à l'interface GTM et permettent facilement le suivi des interactions HTML5 côté client.

Activez les variables d' historique intégrées et créez un déclencheur pour déclencher un événement en fonction des modifications de l'historique.

user2236721
la source
5

Dans votre index.html, copiez et collez l'extrait ga mais supprimez la lignega('send', 'pageview');

<!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
<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','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-XXXXXXXX-X');
</script>

J'aime lui donner son propre fichier d'usine my-google-analytics.jsavec auto-injection:

angular.module('myApp')
  .factory('myGoogleAnalytics', [
    '$rootScope', '$window', '$location', 
    function ($rootScope, $window, $location) {

      var myGoogleAnalytics = {};

      /**
       * Set the page to the current location path
       * and then send a pageview to log path change.
       */
      myGoogleAnalytics.sendPageview = function() {
        if ($window.ga) {
          $window.ga('set', 'page', $location.path());
          $window.ga('send', 'pageview');
        }
      }

      // subscribe to events
      $rootScope.$on('$viewContentLoaded', myGoogleAnalytics.sendPageview);

      return myGoogleAnalytics;
    }
  ])
  .run([
    'myGoogleAnalytics', 
    function(myGoogleAnalytics) {
        // inject self
    }
  ]);
ilovett
la source
J'aime ce truc d'auto-injection :) Up
Sam Vloeberghs
Par simple curiosité, pourquoi définissez-vous pagele chemin actuel, puis soumettez-le en tant que pageview? Quelle est la différence de le faire de cette façon au lieu de simplement $window.ga('send', 'pageview', {page: $location.url()});?
Fizzix
1
Je ne me souviens pas de TBH mais en le regardant, je dirais que cela laisse de la flexibilité pour d'autres actions ou la journalisation de choses supplémentaires ailleurs, et peut être plus précis en indiquant explicitement à ga la page actuelle, afin que ga puisse continuer à fonctionner correctement, plutôt que JUSTE enregistrer une page vue pour une URL de page "arbitraire".
ilovett
Si vous voulez que les analyses en temps réel fonctionnent dans Google, vous devez faire "définir". Pour savoir pourquoi, consultez la référence de la documentation: developers.google.com/analytics/devguides/collection/…
fuzzysearch
'set' est recommandé pour que chaque hit envoyé sur la même page (comme GA Event pour suivre les interactions des utilisateurs) soit envoyé avec la même valeur de chemin de page. Rien à voir avec l'analyse en temps réel. voir developers.google.com/analytics/devguides/collection/…
Open SEO
5

J'ai trouvé que la gtag()fonction fonctionnait, au lieu de la ga()fonction.

Dans le fichier index.html, dans la <head>section:

<script async src="https://www.googletagmanager.com/gtag/js?id=TrackingId"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'TrackingId');
</script>

Dans le code AngularJS:

app.run(function ($rootScope, $location) {
  $rootScope.$on('$routeChangeSuccess', function() {
    gtag('config', 'TrackingId', {'page_path': $location.path()});
  });
});

Remplacez-le TrackingIdpar votre propre identifiant de suivi.

Brent Washburne
la source
4

Si quelqu'un veut implémenter à l'aide de directives, identifiez (ou créez) un div dans le index.html (juste sous la balise body, ou au même niveau DOM)

<div class="google-analytics"/>

puis ajoutez le code suivant dans la directive

myApp.directive('googleAnalytics', function ( $location, $window ) {
  return {
    scope: true,
    link: function (scope) {
      scope.$on( '$routeChangeSuccess', function () {
        $window._gaq.push(['_trackPageview', $location.path()]);
      });
    }
  };
});
coderman
la source
3

Si vous utilisez ui-router, vous pouvez vous abonner à l'événement $ stateChangeSuccess comme ceci:

$rootScope.$on('$stateChangeSuccess', function (event) {
    $window.ga('send', 'pageview', $location.path());
});

Pour un exemple de travail complet, voir cet article de blog

Jason
la source
3

Utilisez GA «set» pour vous assurer que les itinéraires sont récupérés pour les analyses Google en temps réel. Sinon, les appels ultérieurs à GA n'apparaîtront pas dans le panneau en temps réel.

$scope.$on('$routeChangeSuccess', function() {
    $window.ga('set', 'page', $location.url());
    $window.ga('send', 'pageview');
});

Google conseille fortement cette approche au lieu de passer un 3ème paramètre dans "envoyer". https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications

recherche floue
la source
3

Pour ceux d'entre vous qui utilisent AngularUI Router au lieu de ngRoute, vous pouvez utiliser le code suivant pour suivre les pages vues.

app.run(function ($rootScope) {
    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
        ga('set', 'page', toState.url);
        ga('send', 'pageview');
    });
});
Kevin M
la source
3

Les développeurs qui créent des applications à page unique peuvent utiliser le suivi automatique , qui comprend un plugin urlChangeTracker qui gère pour vous toutes les considérations importantes répertoriées dans ce guide. Consultez la documentation autotrack pour les instructions d'utilisation et d'installation.

Abou-Emish
la source
3

J'utilise AngluarJS en mode html5. J'ai trouvé la solution suivante comme la plus fiable:

Utilisez la bibliothèque angular-google-analytics . Initialisez-le avec quelque chose comme:

//Do this in module that is always initialized on your webapp    
angular.module('core').config(["AnalyticsProvider",
  function (AnalyticsProvider) {
    AnalyticsProvider.setAccount(YOUR_GOOGLE_ANALYTICS_TRACKING_CODE);

    //Ignoring first page load because of HTML5 route mode to ensure that page view is called only when you explicitly call for pageview event
    AnalyticsProvider.ignoreFirstPageLoad(true);
  }
]);

Après cela, ajoutez l'écouteur sur $ stateChangeSuccess 'et envoyez l'événement trackPage.

angular.module('core').run(['$rootScope', '$location', 'Analytics', 
    function($rootScope, $location, Analytics) {
        $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams, options) {
            try {
                Analytics.trackPage($location.url());
            }
            catch(err) {
              //user browser is disabling tracking
            }
        });
    }
]);

À tout moment, lorsque votre utilisateur est initalisé, vous pouvez y injecter Analytics et appeler:

Analytics.set('&uid', user.id);
maleta
la source
2

J'utilise ui-router et mon code ressemble à ceci:

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams){
  /* Google analytics */
  var path = toState.url;
  for(var i in toParams){
    path = path.replace(':' + i, toParams[i]);
  }
  /* global ga */
  ga('send', 'pageview', path);
});

De cette façon, je peux suivre différents états. Peut-être que quelqu'un le trouvera utile.

Miha Eržen
la source
1

Personnellement, j'aime configurer mes analyses avec l'URL du modèle au lieu du chemin actuel. Ceci est principalement dû au fait que mon application possède de nombreux chemins personnalisés tels que message/:idou profile/:id. Si je devais envoyer ces chemins, j'aurais tellement de pages visualisées dans Analytics, il serait trop difficile de vérifier quelle page les utilisateurs visitent le plus.

$rootScope.$on('$viewContentLoaded', function(event) {
    $window.ga('send', 'pageview', {
        page: $route.current.templateUrl.replace("views", "")
    });
});

J'obtiens désormais des pages propres dans mes analyses, telles que user-profile.htmlet message.htmlau lieu de nombreuses pages profile/1, profile/2et profile/3. Je peux maintenant traiter des rapports pour voir combien de personnes consultent les profils utilisateur.

Si quelqu'un s'oppose à la raison pour laquelle il s'agit d'une mauvaise pratique en matière d'analyse, je serais plus qu'heureux d'en entendre parler. Tout nouveau dans l'utilisation de Google Analytics, donc pas trop sûr si c'est la meilleure approche ou non.

Fizzix
la source
1

Je suggère d'utiliser la bibliothèque d'analyse de segment et de suivre notre guide de démarrage rapide angulaire . Vous pourrez suivre les visites de pages et suivre les actions du comportement des utilisateurs avec une seule API. Si vous avez un SPA, vous pouvez autoriser le RouterOutletcomposant à gérer le rendu de la page et à l'utiliser ngOnInitpour appeler des pageappels. L'exemple ci-dessous montre une façon de procéder:

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  ngOnInit() {
    window.analytics.page('Home');
  }
}

Je suis le responsable de https://github.com/segmentio/analytics-angular . Avec Segment, vous pourrez activer et désactiver différentes destinations en appuyant sur un commutateur si vous souhaitez essayer plusieurs outils d'analyse (nous prenons en charge plus de 250+ destinations) sans avoir à écrire de code supplémentaire. 🙂

William
la source
0

Fusionner encore plus avec la réponse de Pedro Lopez,

J'ai ajouté ceci à mon module ngGoogleAnalytis (que je réutilise dans de nombreuses applications):

var base = $('base').attr('href').replace(/\/$/, "");

dans ce cas, j'ai une balise dans mon lien d'index:

  <base href="/store/">

il est utile lors de l'utilisation du mode html5 sur angular.js v1.3

(supprimez l'appel de la fonction replace () si votre balise de base ne se termine pas par une barre oblique /)

angular.module("ngGoogleAnalytics", []).run(['$rootScope', '$location', '$window',
    function($rootScope, $location, $window) {
      $rootScope.$on('$routeChangeSuccess',
        function(event) {
          if (!$window.ga) { return; }
          var base = $('base').attr('href').replace(/\/$/, "");

          $window.ga('send', 'pageview', {
            page: base + $location.path()
          });
        }
      );
    }
  ]);
Felipe Sousa Iketani
la source
-3

Si vous recherchez le contrôle total du nouveau code de suivi de Google Analytics, vous pouvez utiliser mon propre Angular-GA .

Il est gadisponible par injection, il est donc facile à tester. Cela ne fait aucune magie, à part définir le chemin sur chaque routeChange. Vous devez toujours envoyer la page vue comme ici.

app.run(function ($rootScope, $location, ga) {
    $rootScope.$on('$routeChangeSuccess', function(){
        ga('send', 'pageview');
    });
});

De plus, il existe une directive gaqui permet de lier plusieurs fonctions d'analyse à des événements, comme ceci:

<a href="#" ga="[['set', 'metric1', 10], ['send', 'event', 'player', 'play', video.id]]"></a>
Rafał Lindemann
la source