web-dev-qa-db-fra.com

Suivi des pages vues de Google Analytics avec AngularJS

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

220
dj2

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

En supposant que vous ayez configuré votre code de suivi dans votre fichier principal index.html avec le nom var _gaq et que MyCtrl correspond à ce que vous avez défini dans la directive ng-controller.

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

PDATE: pour la 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() });
  });
}
240
dj2

Lorsqu'une nouvelle vue est chargée dans AngularJS, Google Analytics ne la considère pas comme un nouveau chargement de page. Heureusement, il existe un moyen d'indiquer manuellement à GA de consigner une URL sous la forme d'une nouvelle page vue.

_gaq.Push(['_trackPageview', '<url>']); ferait le travail, mais comment le lier à 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 angular, incluez-le comme suit:

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

UPDATE:

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

$window.ga('send', 'pageview', {page: $location.url()});
57
Haralan Dobrev
app.run(function ($rootScope, $location) {
    $rootScope.$on('$routeChangeSuccess', function(){
        ga('send', 'pageview', $location.path());
    });
});
48
dpineda

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

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

En outre, un conseil est que Google Analytics ne se déclenchera pas sur localhost. Donc, si vous testez sur localhost, utilisez ce qui suit au lieu de créer par défaut ( documentation complète )

ga('create', 'UA-XXXX-Y', {'cookieDomain': 'none'});
40
wynnwu

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

Départ https://github.com/mgonto/angularytics et laissez-moi savoir comment cela fonctionne pour vous.

11
mgonto

La fusion des réponses de Wynnwu et de 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 ont été décisifs.

J'espère que cela t'aides.

10
Pedro Lopez

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

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

7
IBootstrap

Pour ce faire, le meilleur moyen consiste à utiliser Google Tag Manager pour activer vos tags Google Analytics en fonction des écouteurs de l'historique. Celles-ci sont intégrées à l'interface GTM et permettent un suivi facile des interactions HTML5 côté client.

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

4
user2236721

J'ai trouvé que la fonction gtag() fonctionnait à la place de la fonction ga().

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

<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 TrackingId par votre propre identifiant de suivi.

4
Brent Washburne

Si quelqu'un souhaite implémenter des directives d'utilisation, identifiez (ou créez) une div dans le fichier index.html (juste sous la balise body ou au même niveau de 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()]);
      });
    }
  };
});
4
coderman

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

3
Jason

Utilisez GA 'set' pour vous assurer que les itinéraires sont sélectionné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 vivement cette approche en général au lieu de passer un 3ème paramètre dans "envoyer". https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications

3
fuzzysearch

J'utilise AngluarJS en mode html5. J'ai trouvé la solution suivante 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 un écouteur sur $ stateChangeSuccess 'et envoyez un é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 hospitalisé, vous pouvez y injecter Analytics et passer un appel:

Analytics.set('&uid', user.id);
3
Maleta

Dans votre index.html, copiez et collez l'extrait de code, mais supprimez la ligne ga('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.js avec 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
    }
  ]);
3
ilovett

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.

2
Miha Eržen

Les développeurs qui créent des applications à une seule page peuvent utiliser autotrack , qui inclut un plugin rlChangeTracker , qui traite pour vous toutes les considérations importantes énumérées dans ce guide. Voir le documentation autotrack pour les instructions d’utilisation et d’installation.

2
Abou-Emish

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

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

Personnellement, j'aime bien configurer mes analyses avec l'URL du modèle au lieu du chemin actuel. Cela est principalement dû au fait que mon application comporte de nombreux chemins personnalisés, tels que message/:id ou profile/:id. Si je devais envoyer ces chemins, j'aurais tellement de pages vues dans l'analyse, il serait trop difficile de vérifier quelles pages sont les utilisateurs les plus visités.

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

Mes analyses contiennent désormais des vues propres, telles que user-profile.html et message.html au lieu de nombreuses pages comme profile/1, profile/2 et profile/3. Je peux maintenant traiter les rapports pour voir combien de personnes consultent les profils d'utilisateurs.

Si quelqu'un s'oppose à la raison pour laquelle il s'agit d'une mauvaise pratique en matière d'analyse, je serais ravi de l'entendre. C'est assez nouveau d'utiliser Google Analytics, donc ne savez pas trop s'il s'agit ou non de la meilleure approche.

1
Fizzix

Je suggère d'utiliser la bibliothèque d'analyse de segment et de suivre notre Guide de démarrage rapide angulaire . Vous serez en mesure de suivre les visites de pages et les actions de comportement des utilisateurs avec une seule API. Si vous avez un SPA, vous pouvez autoriser le composant RouterOutlet à gérer le rendu de la page et utiliser ngOnInit pour appeler des appels page. 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 un tournemain si vous souhaitez essayer plusieurs outils d'analyse (nous prenons en charge plus de 250 destinations) sans avoir à écrire de code supplémentaire. ????

1
William

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 un tag dans mon lien d'index:

  <base href="/store/">

c'est utile lorsque vous utilisez le mode html5 sur angular.js v1.3

(supprime 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()
          });
        }
      );
    }
  ]);
0