Verfolgen von Google Analytics-Seitenaufrufen mit AngularJS


221

Ich richte eine neue App mit AngularJS als Frontend ein. Alles auf der Clientseite wird mit HTML5 Pushstate erledigt und ich möchte meine Seitenaufrufe in Google Analytics verfolgen können.


Versuchen Sie Angulartics luisfarzati.github.io/angulartics
David

2
Angulartik ist veraltet. Verwenden Sie
Angular

5
@ webdev5 Eine neue Version von Angulartics ist da. Probieren Sie es aus bei: angulartics.github.io
Devner

Antworten:


240

Wenn Sie ng-viewin Ihrer Angular-App verwenden, können Sie auf das $viewContentLoadedEreignis warten und ein Tracking-Ereignis an Google Analytics senden.

Angenommen, Sie haben Ihren Tracking-Code in Ihrer Hauptdatei index.html mit dem Namen var _gaqund MyCtrl eingerichtet, wie Sie es in der ng-controllerDirektive definiert haben .

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

UPDATE: Verwenden Sie für eine neue Version von Google Analytics diese

function MyCtrl($scope, $location, $window) {
  $scope.$on('$viewContentLoaded', function(event) {
    $window.ga('send', 'pageview', { page: $location.url() });
  });
}

12
FWIW sollte es sein _trackPageviewund nicht _trackPageView... verbrachte 10 Minuten am Kopf kratzen :)
Sajal

123
Ich würde $rootScope.$on('$routeChangeSuccess', ...)
Bärenfreund

5
@DavidRivers Hm, es ist schon eine Weile her, aber nur wenn man sich diese Antwort und meinen Kommentar ansieht, scheint es, als $rootScopewürde die Anwendung auf garantieren, dass sie nicht durch ein anderes Ereignis oder eine andere DOM-Änderung entfernt wird, und die Verwendung routeChangeSuccesswird jedes Mal ausgelöst, wenn die Die Positionsleiste ändert sich, anstatt immer Ihre Quellquelle zu ändern. Ist das sinnvoll?
Bärenfreund

5
@ dg988 Während eines $ routeChangeSuccess-Ereignisses kennen Sie möglicherweise NICHT den Titel der Seite im Voraus (der beispielsweise in einem Controller festgelegt werden kann, nachdem die Verarbeitung von Daten aus einem RESTful-Dienst abgeschlossen wurde). Auf diese Weise verfolgt Google Analytics allein mit der URL der Seite einen Titel der vorherigen Seite.
Konstantin Tarkus

43
Wenn Sie das neue GA-Skript verwenden, ist es $window.ga('send', 'pageview', { page: $location.path() });anstelle des $window._gaq...Teils. Möglicherweise möchten Sie auch ga('send', 'pageview');aus Ihrem ursprünglichen GA-Code entfernen , um Duplikate zu vermeiden, wenn Sie zum ersten Mal auf einer Seite landen.
CWSpear

57

Wenn eine neue Ansicht geladen wird AngularJS, zählt Google Analytics sie nicht als neue Seitenladung. Glücklicherweise gibt es eine Möglichkeit, GA manuell anzuweisen, eine URL als neuen Seitenaufruf zu protokollieren.

_gaq.push(['_trackPageview', '<url>']); würde den Job machen, aber wie kann man das mit AngularJS binden?

Hier ist ein Dienst, den Sie nutzen können:

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

Wenn Sie Ihr Winkelmodul definieren, fügen Sie das Analysemodul folgendermaßen hinzu:

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

UPDATE :

Sie sollten den neuen Universal Google Analytics-Tracking-Code verwenden mit:

$window.ga('send', 'pageview', {page: $location.url()});

6
Die andere Sache, die Sie hier beachten sollten, ist, dass Sie den "Analytics" -Dienst irgendwo einbinden müssen. Ich habe meine in app.run gemacht.
Nix

Würde dies in jedem Modul oder nur in der ersten App enthalten sein müssen?
Designermonkey

2
@Designermonkey Es sollte funktionieren, wenn Sie nur in Ihr Haupt-App-Modul aufnehmen. Wenn Sie jedoch ein völlig unabhängiges Modul haben, für das Ihr Hauptmodul nicht erforderlich ist, müssen Sie es möglicherweise erneut einbinden. Prost!
Haralan Dobrev

Wenn Sie einen Dienst verwenden, sollten Sie Ihre Funktionen mit dem Schlüsselwort "this" definieren: source . Zum Beispiel innerhalb des Dienstes wäre dies this.track = function($window.ga('send', 'pageview', {page: $location.url()});Dies ermöglicht es Ihnen, googleAnalytics.track();innerhalb Ihrer app.run () Funktion zu verwenden
zcoon

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

8
Hinweis: Wenn Sie Minimierung / Kompilierung verwenden, müssen Sie die Parameternamen angeben:app.run(["$rootScope", "$location", function(...
dplass

Diese Lösung eignet sich hervorragend, wenn Sie nicht in jedem Controller GA-Code einfügen möchten.
Breez

1
Nicht so toll, wenn Sie asynchronen Code haben, der Ihren Titel dynamisch ändert, sonst ist er großartig.
Johan

40

Nur eine kurze Ergänzung. Wenn Sie die neue Datei analyse.js verwenden, gilt Folgendes:

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

Ein Tipp ist außerdem, dass Google Analytics nicht auf localhost ausgelöst wird. Wenn Sie also auf localhost testen, verwenden Sie anstelle der Standarderstellung Folgendes ( vollständige Dokumentation ).

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

Oh Mann, danke. Ich bekam seltsame Fehler und bemerkte, dass mein Snippet nicht einmal _gaq enthielt, hehe. Dumme Google: Aktualisierung ihres Codes und all das! Haha.
CWSpear

3
Stellen Sie sicher, dass Sie $windowfür den Zugriff auf das Fenster verwenden ( gaallein in Angular ist dies sehr wahrscheinlich undefined). Möglicherweise möchten Sie auch ga('send', 'pageview');aus Ihrem ursprünglichen GA-Code entfernen , um Duplikate zu vermeiden, wenn Sie zum ersten Mal auf einer Seite landen.
CWSpear

6
Mit UI-Router können Sie Seitenaufrufe wie $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { ga('send', 'pageview', { 'page': $location.path(), 'title': toState.name }); });
folgt

2
Hinzufügen: Wenn Sie Suchparameter in Ihrer App verwenden, können Sie diese mit$location.url()
Ade

2
Ich habe diese Antwort positiv bewertet, da die Verwendung von .path () besser ist als .url (), da Sie normalerweise Parameter für Abfragezeichenfolgen ausschließen möchten. Siehe: Google Analytics-Konfigurationsfehler Nr. 2:
Abfragezeichenfolgenvariablen

11

Ich habe einen Service + Filter erstellt, der Ihnen dabei helfen kann, und vielleicht auch bei einigen anderen Anbietern, wenn Sie diese in Zukunft hinzufügen möchten.

Schauen Sie sich https://github.com/mgonto/angularytics an und lassen Sie mich wissen, wie dies für Sie funktioniert.


10

Das Zusammenführen der Antworten von Wynnwu und Dpineda hat für mich funktioniert.

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

Das Festlegen des dritten Parameters als Objekt (anstelle von nur $ location.path ()) und die Verwendung von $ routeChangeSuccess anstelle von $ stateChangeSuccess haben den Trick ausgeführt.

Hoffe das hilft.


7

Ich habe ein einfaches Beispiel für Github mit dem obigen Ansatz erstellt.

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


Ich habe einen Fix hinzugefügt, um den Pfad besser zu melden. Wenn Sie also die Route /account/:accountId aka aka path http://somesite.com/account/123haben, wird der Pfad jetzt als/account?accountId=123
IBootstrap

@IBootstrap Was ist der Vorteil, wenn die Routenparameter in die Abfragezeichenfolge eingefügt werden?
Pavel Nikolov

@IBootstrap Ich habe die gleiche Frage: Was bringt es, die Routenparameter in die Abfragezeichenfolge einzufügen?
Dzung Nguyen

1
Nicht alle Routen sind unterschiedliche Seiten, und GA behandelt jede Route als unterschiedliche Seite. Durch Konvertieren der Route in eine Abfragezeichenfolge haben Sie die Möglichkeit, Teile der Abfragezeichenfolge zu ignorieren.
IBootstrap

5

Der beste Weg, dies zu tun, ist die Verwendung von Google Tag Manager, um Ihre Google Analytics-Tags basierend auf Verlaufs-Listenern auszulösen. Diese sind in die GTM-Oberfläche integriert und ermöglichen auf einfache Weise die Verfolgung clientseitiger HTML5-Interaktionen.

Aktivieren Sie die integrierte History Variablen und erstellen Sie einen Trigger ein Ereignis ausgelöst , basierend auf der Geschichte ändert.


5

index.htmlKopieren Sie das ga-Snippet und fügen Sie es ein , aber entfernen Sie die Liniega('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>

Ich gebe ihm gerne eine eigene Factory-Datei my-google-analytics.jsmit Selbstinjektion:

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

Ich mag das Selbstinjektionsmaterial :) Up
Sam Vloeberghs

Warum setzen Sie aus Neugier den pagemit dem aktuellen Pfad und reichen ihn dann als ein pageview? Was ist der Unterschied, wenn man es so macht, anstatt nur $window.ga('send', 'pageview', {page: $location.url()});?
Fizzix

1
Ich kann mich nicht an TBH erinnern, aber wenn ich es mir anschaue, würde ich sagen, dass es Flexibilität für andere Aktionen oder das Protokollieren zusätzlicher Dinge an anderer Stelle lässt und möglicherweise genauer ist, wenn ga der aktuellen Seite explizit mitgeteilt wird, sodass ga weiterhin genau funktionieren kann und nicht Protokollieren Sie einfach einen Seitenaufruf für eine "beliebige" Seiten-URL.
Ilovett

Wenn Sie möchten, dass Echtzeitanalysen in Google funktionieren, sollten Sie "set" ausführen. Weitere
Informationen finden

'set' wird empfohlen, damit jeder einzelne Treffer, der auf derselben Seite gesendet wird (wie GA Event zur Verfolgung von Benutzerinteraktionen), mit demselben Seitenpfadwert gesendet wird. Nichts mit Echtzeitanalysen zu tun. Siehe developer.google.com/analytics/devguides/collection/…
Öffnen Sie SEO

5

Ich fand die gtag()Funktion funktioniert, anstelle der ga()Funktion.

In der Datei index.html im <head>Abschnitt:

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

Im AngularJS-Code:

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

Ersetzen Sie TrackingIddurch Ihre eigene Tracking-ID.


4

Wenn jemand mithilfe von Anweisungen implementieren möchte, identifizieren (oder erstellen) Sie ein div in der index.html (direkt unter dem Body-Tag oder auf derselben DOM-Ebene).

<div class="google-analytics"/>

und fügen Sie dann den folgenden Code in die Direktive ein

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

3

Wenn Sie einen UI-Router verwenden, können Sie das Ereignis $ stateChangeSuccess wie folgt abonnieren:

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

Ein vollständiges Arbeitsbeispiel finden Sie in diesem Blogbeitrag


3

Verwenden Sie GA 'set', um sicherzustellen, dass Routen für Google-Echtzeitanalysen erfasst werden. Andernfalls werden nachfolgende Anrufe bei GA nicht im Echtzeitfenster angezeigt.

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

Google empfiehlt diesen Ansatz generell dringend, anstatt einen dritten Parameter in "Senden" zu übergeben. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications


3

Wenn Sie AngularUI Router anstelle von ngRoute verwenden, können Sie den folgenden Code verwenden, um Seitenaufrufe zu verfolgen.

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


3

Ich benutze AngluarJS im HTML5-Modus. Ich fand folgende Lösung als am zuverlässigsten:

Verwenden Sie die Angular-Google-Analytics- Bibliothek. Initialisieren Sie es mit etwas wie:

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

Fügen Sie danach den Listener für $ stateChangeSuccess 'hinzu und senden Sie das trackPage-Ereignis.

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

Wenn Sie Ihren Benutzer initialisiert haben, können Sie jederzeit Analytics dort injizieren und einen Anruf tätigen:

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

2

Ich benutze UI-Router und mein Code sieht folgendermaßen aus:

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

Auf diese Weise kann ich verschiedene Zustände verfolgen. Vielleicht findet es jemand nützlich.


1

Ich persönlich möchte meine Analyse mit der Vorlagen-URL anstelle des aktuellen Pfads einrichten. Dies liegt hauptsächlich daran, dass meine Anwendung viele benutzerdefinierte Pfade wie message/:idoder hat profile/:id. Wenn ich diese Pfade senden würde, würden so viele Seiten in Analytics angezeigt, dass es zu schwierig wäre, zu überprüfen, welche Seite Benutzer am häufigsten besuchen.

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

Ich erhalte jetzt saubere Seitenaufrufe in meinen Analysen, z. B. user-profile.htmlund message.htmlstatt vieler Seiten profile/1, profile/2und profile/3. Ich kann jetzt Berichte verarbeiten, um zu sehen, wie viele Personen Benutzerprofile anzeigen.

Wenn jemand Einwände dagegen hat, warum dies eine schlechte Praxis in der Analytik ist, würde ich mich sehr freuen, davon zu hören. Ganz neu in der Verwendung von Google Analytics, daher nicht sicher, ob dies der beste Ansatz ist oder nicht.


1

Ich empfehle, die Segmentanalysebibliothek zu verwenden und unserer Angular-Kurzanleitung zu folgen . Mit einer einzigen API können Sie Seitenbesuche und Benutzerverhaltensaktionen verfolgen. Wenn Sie eine SPA haben, können Sie die erlauben RouterOutletKomponente Griff , wenn die Seite macht und die Nutzung ngOnInitaufzurufen pageAnrufe. Das folgende Beispiel zeigt eine Möglichkeit, wie Sie dies tun können:

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

Ich bin der Betreuer von https://github.com/segmentio/analytics-angular . Mit Segment können Sie verschiedene Ziele durch Umlegen eines Schalters ein- und ausschalten, wenn Sie mehrere Analysetools ausprobieren möchten (wir unterstützen über 250 Ziele), ohne zusätzlichen Code schreiben zu müssen. 🙂


0

Noch mehr mit Pedro Lopez 'Antwort verschmelzen,

Ich habe dies meinem ngGoogleAnalytis-Modul hinzugefügt (das ich in vielen Apps wiederverwenden kann):

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

In diesem Fall habe ich ein Tag in meinem Indexlink:

  <base href="/store/">

Dies ist nützlich, wenn Sie den HTML5-Modus für angle.js v1.3 verwenden

(Entfernen Sie den Funktionsaufruf replace (), wenn Ihr Basis-Tag nicht mit einem Schrägstrich / endet.)

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

-3

Wenn Sie die vollständige Kontrolle über den neuen Tracking-Code von Google Analytics suchen, können Sie meinen eigenen Angular-GA verwenden .

Es wird gadurch Injektion verfügbar gemacht und ist daher leicht zu testen. Es macht keine Magie, außer den Pfad auf jeder routeChange festzulegen. Sie müssen den Seitenaufruf noch wie hier senden.

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

Zusätzlich gibt es eine Direktive, gadie es ermöglicht, mehrere Analysefunktionen an Ereignisse wie diese zu binden:

<a href="#" ga="[['set', 'metric1', 10], ['send', 'event', 'player', 'play', video.id]]"></a>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.