Śledzenie wyświetleń strony Google Analytics za pomocą AngularJS


221

Konfiguruję nową aplikację, używając AngularJS jako interfejsu. Wszystko po stronie klienta odbywa się za pomocą pushstate HTML5 i chciałbym móc śledzić moje wyświetlenia stron w Google Analytics.



2
angulartics jest przestarzałe. Użyj
— angular

5
@ webdev5 Nowa wersja angulartics jest dostępna. Wypróbuj na: angulartics.github.io
— Devner

Odpowiedzi:


240

Jeśli korzystasz ng-viewz aplikacji Angular, możesz nasłuchiwać $viewContentLoadedwydarzenia i przekazywać zdarzenia śledzenia do Google Analytics.

Zakładając, że masz ustawiony kod śledzenia w głównym pliku index.html o nazwie var _gaqi MyCtrl jest tym, co zdefiniowałeś w ng-controllerdyrektywie.

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

AKTUALIZACJA: do nowej wersji google-analytics użyj tej

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

12
FWIW powinno być _trackPageviewi nie _trackPageView... spędziłem 10 minut drapania głowy :)
— sajal

123
Użyłbym $rootScope.$on('$routeChangeSuccess', ...)
— bearfriend

5
@DavidRivers Hm, minęło trochę czasu, ale po spojrzeniu na tę odpowiedź i mój komentarz wydaje się, że zastosowanie jej $rootScopezagwarantuje, że nie zostanie ona usunięta przez inne wydarzenie lub zmianę DOM, a użycie routeChangeSuccessbędzie uruchamiane za każdym razem, gdy zmienia się pasek adresu, zamiast zmieniać szablon źródła widoku. Czy to ma sens?
— Niedźwiedź

5
@ dg988 podczas zdarzenia $ routeChangeSuccess, możesz NIE wiedzieć z góry tytułu strony (który, na przykład, można ustawić w kontrolerze po zakończeniu przetwarzania danych z usługi RESTful). W ten sposób sam z adresem URL strony Google Analytics będzie śledzić tytuł poprzedniej strony.
— Konstantin Tarkus,

43
Jeśli używasz nowego skryptu GA, to $window.ga('send', 'pageview', { page: $location.path() });zamiast $window._gaq...części. Możesz też chcieć usunąć ga('send', 'pageview');z oryginalnego kodu GA, aby zapobiec duplikatom przy pierwszym lądowaniu na stronie.
— CWSpear,

57

Po załadowaniu nowego widoku AngularJSGoogle Analytics nie liczy go jako wczytywania nowej strony. Na szczęście istnieje sposób, aby ręcznie powiedzieć GA, aby zalogował adres URL jako nową odsłonę.

_gaq.push(['_trackPageview', '<url>']); zrobiłby to zadanie, ale jak powiązać to z AngularJS?

Oto usługa, z której możesz skorzystać:

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

Podczas definiowania modułu kątowego dołącz moduł analityczny w następujący sposób:

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

AKTUALIZACJA :

Powinieneś użyć nowego kodu śledzenia Universal Google Analytics z:

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

6
Inną rzeczą wartą odnotowania jest to, że musisz gdzieś dołączyć usługę „analityczną”. Zrobiłem mój w app.run.
— Nix

Czy będzie to konieczne w każdym module, czy tylko w początkowej aplikacji?
— designermonkey

2
@Designermonkey Powinno działać, jeśli podasz tylko w głównym module aplikacji. Jeśli masz całkowicie niezależny moduł, który nie wymaga modułu głównego, konieczne może być ponowne włączenie go. Twoje zdrowie!
— Haralan Dobrev

Jeśli korzystasz z usługi, powinieneś zdefiniować swoje funkcje za pomocą słowa kluczowego „this”: source . Na przykład, w ramach usługi byłoby this.track = function($window.ga('send', 'pageview', {page: $location.url()});Pozwoli to na użycie googleAnalytics.track();w swoim app.run () funkcja
— zcoon

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

8
Uwaga: Jeśli używasz minimalizacji / kompilacji, musisz podać nazwy parametrów:app.run(["$rootScope", "$location", function(...
— dplass

To rozwiązanie jest doskonałe, jeśli nie chcesz dołączać kodu GA do każdego kontrolera.
— breez

1
Nie tak świetnie, jeśli masz kod asynchroniczny, który dynamicznie zmienia tytuł, w przeciwnym razie jest świetny.
— Johan

40

Szybki dodatek. Jeśli używasz nowego pliku analytics.js, to:

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

Dodatkowo jedna wskazówka jest taka, że ​​Google Analytics nie uruchomi się na localhost. Więc jeśli testujesz na localhost, użyj następującego zamiast domyślnego tworzenia ( pełna dokumentacja )

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

O rany, dzięki. Miałem dziwne błędy i zauważyłem, że mój fragment nie ma nawet _gaq, hehe. Silly Google: aktualizacja ich kodu i tak dalej! Ha ha.
— CWSpear,

3
Upewnij się, że używasz, $windowaby uzyskać dostęp do okna ( gaprawdopodobnie wewnątrz Angular prawdopodobnie będzie undefined). Możesz też chcieć usunąć ga('send', 'pageview');z oryginalnego kodu GA, aby zapobiec duplikatom przy pierwszym lądowaniu na stronie.
— CWSpear,

6
Za pomocą interfejsu użytkownika routera można wysyłać wyświetlenia stron w następujący sposób:$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { ga('send', 'pageview', { 'page': $location.path(), 'title': toState.name }); });
— pherris

2
Aby dodać: Jeśli używasz parametrów wyszukiwania w swojej aplikacji, możesz śledzić te, które używają$location.url()
— Ade

2
Poprosiłem tę odpowiedź, ponieważ użycie .path () jest lepsze niż .url (), ponieważ zwykle chcesz wykluczyć parametry ciągu zapytania. Zobacz: Błąd konfiguracji Google Analytics nr 2: zmienne
— ciągu


10

Dla mnie zadziałało połączenie odpowiedzi wynnwu i dpineda.

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

Ustawienie trzeciego parametru jako obiektu (zamiast tylko $ location.path ()) i użycie $ routeChangeSuccess zamiast $ stateChangeSuccess załatwiło sprawę.

Mam nadzieję że to pomoże.


7

Stworzyłem prosty przykład na github, stosując powyższe podejście.

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


Dodałem poprawkę, aby lepiej zgłosić ścieżkę. więc teraz, jeśli masz trasę /account/:accountId ścieżki aka, http://somesite.com/account/123to teraz zgłosi ścieżkę jako/account?accountId=123
— IBootstrap

@IBootstrap jaka jest korzyść z umieszczenia parametrów trasy w ciągu zapytania?
— Pavel Nikolov

@IBootstrap Mam to samo pytanie, jaka jest korzyść z umieszczenia parametrów trasy w ciągu zapytania?
— Dzung Nguyen

1
Nie wszystkie trasy są różnymi stronami, a GA traktuje każdą trasę jako inną stronę. Konwertując trasę na ciąg zapytania, możesz zignorować części ciągu zapytania.
— IBootstrap

5

Najlepszym sposobem na to jest użycie Menedżera tagów Google do uruchomienia tagów Google Analytics na podstawie detektorów historii. Są one wbudowane w interfejs GTM i umożliwiają łatwe śledzenie interakcji HTML5 po stronie klienta.

Włącz wbudowane zmienne Historia i utwórz wyzwalacz, aby uruchomić zdarzenie na podstawie zmian historii.


5

W twojej index.html, skopiować i wkleić fragment ga jednak usunąć wierszga('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>

Lubię nadać mu własny plik fabryczny my-google-analytics.jsz własnym zastrzykiem:

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

Lubię te rzeczy do samodzielnego wstrzykiwania :) Up
— Sam Vloeberghs,

Właśnie z ciekawości, dlaczego ustawiasz pagebieżącą ścieżkę, a następnie przesyłasz ją jako pageview? Jaka jest różnica w robieniu tego w ten sposób zamiast po prostu $window.ga('send', 'pageview', {page: $location.url()});?
— Fizzix,

1
Nie pamiętam TBH, ale patrząc na to powiedziałbym, że pozostawia elastyczność na inne działania lub rejestrowanie dodatkowych rzeczy w innym miejscu, i może być bardziej dokładny poprzez jawne wskazanie ga bieżącej strony, więc ga może nadal działać poprawnie, a nie PO PROSTU rejestrowanie odsłon dla jakiegoś „dowolnego” adresu URL.
— ilovett

Jeśli chcesz, aby analityka czasu rzeczywistego działała w Google, powinieneś „ustawić”. Informacje na ten temat można znaleźć w dokumentacji dokumentacji: developers.google.com/analytics/devguides/collection/…
— fuzzysearch

„set” jest zalecane, aby każde pojedyncze trafienie wysyłane na tej samej stronie (np. GA Event do śledzenia interakcji użytkownika) było wysyłane z tą samą wartością ścieżki strony. Nie ma nic wspólnego z analizami w czasie rzeczywistym. zobacz developers.google.com/analytics/devguides/collection/…
— Otwórz SEO

5

Odkryłem, że gtag()funkcja działała, zamiast ga()funkcji.

W pliku index.html w <head>sekcji:

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

W kodzie AngularJS:

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

Zamień TrackingIdna własny identyfikator śledzenia.


4

Jeśli ktoś chce zaimplementować za pomocą dyrektyw, zidentyfikuj (lub utwórz) div w pliku index.html (tuż pod tagiem body lub na tym samym poziomie DOM)

<div class="google-analytics"/>

a następnie dodaj następujący kod do dyrektywy

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

3

Jeśli używasz interfejsu użytkownika, możesz zasubskrybować zdarzenie $ stateChangeSuccess w następujący sposób:

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

Aby uzyskać pełny działający przykład, zobacz ten post na blogu


3

Użyj GA „ustaw”, aby upewnić się, że są wybierane trasy do analizy Google w czasie rzeczywistym. W przeciwnym razie kolejne połączenia z GA nie będą wyświetlane w panelu w czasie rzeczywistym.

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

Google zdecydowanie zaleca takie podejście, zamiast przekazywać trzeci parametr w „send”. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications


3

Użytkownicy korzystający z AngularUI Router zamiast ngRoute mogą użyć następującego kodu do śledzenia wyświetleń stron.

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


3

Używam AngluarJS w trybie HTML5. Znalazłem następujące rozwiązanie jako najbardziej niezawodne:

Użyj biblioteki angular-google-analytics . Zainicjuj to za pomocą czegoś takiego:

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

Następnie dodaj detektor do $ stateChangeSuccess 'i wyślij zdarzenie 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
            }
        });
    }
]);

W dowolnym momencie po zainicjowaniu użytkownika możesz wprowadzić tam Analytics i zadzwonić:

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

2

Używam interfejsu użytkownika i mój kod wygląda następująco:

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

W ten sposób mogę śledzić różne stany. Może ktoś uzna to za przydatne.


1

Osobiście lubię konfigurować dane analityczne z adresem URL szablonu zamiast bieżącej ścieżki. Wynika to głównie z tego, że moja aplikacja ma wiele niestandardowych ścieżek, takich jak message/:idlub profile/:id. Gdybym wysłał te ścieżki, miałbym tak wiele stron przeglądanych w ramach analizy, zbyt trudno byłoby sprawdzić, którzy użytkownicy odwiedzają najwięcej.

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

W mojej analizie uzyskuję teraz czyste wyświetlenia stron, takie jak user-profile.htmli message.htmlzamiast wielu stron profile/1, profile/2i profile/3. Teraz mogę przetwarzać raporty, aby zobaczyć, ile osób przegląda profile użytkowników.

Jeśli ktoś ma jakiś sprzeciw wobec tego, dlaczego jest to zła praktyka w zakresie analiz, chętnie o tym usłyszę. Zupełnie nowy w korzystaniu z Google Analytics, więc nie jestem pewien, czy jest to najlepsze podejście, czy nie.


1

Sugeruję skorzystanie z biblioteki analitycznej Segment i skorzystanie z naszego przewodnika Szybki start Angular . Będziesz mógł śledzić odwiedziny na stronie i działania użytkownika za pomocą jednego interfejsu API. Jeśli masz SPA, możesz pozwolić RouterOutletkomponentowi na obsługę podczas renderowania strony i używać go ngOnInitdo wywoływania pagepołączeń. Poniższy przykład pokazuje jeden ze sposobów, w jaki możesz to zrobić:

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

Jestem opiekunem https://github.com/segmentio/analytics-angular . Dzięki Segment będziesz mógł włączać i wyłączać różne miejsca docelowe jednym naciśnięciem przycisku, jeśli chcesz wypróbować wiele narzędzi analitycznych (obsługujemy ponad 250 miejsc docelowych) bez konieczności pisania dodatkowego kodu. 🙂


0

Łącząc się jeszcze bardziej z odpowiedzią Pedro Lopeza,

Dodałem to do mojego modułu ngGoogleAnalytis (którego używam ponownie w wielu aplikacjach):

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

w tym przypadku mam link w indeksie:

  <base href="/store/">

przydaje się, gdy używasz trybu HTML5 na angular.js v1.3

(usuń wywołanie funkcji replace (), jeśli tag podstawowy nie kończy się ukośnikiem /)

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

Jeśli szukasz pełnej kontroli nad nowym kodem śledzenia Google Analytics, możesz użyć mojego własnego Angular-GA .

To sprawia, że gadostępne poprzez iniekcję, więc jest to łatwe do testu. Nie robi żadnej magii, oprócz ustawiania ścieżki na każdej trasie Zmień. Nadal musisz wysłać odsłonę, tak jak tutaj.

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

Dodatkowo istnieje dyrektywa, gaktóra pozwala powiązać wiele funkcji analitycznych ze zdarzeniami, takimi jak:

<a href="#" ga="[['set', 'metric1', 10], ['send', 'event', 'player', 'play', video.id]]"></a>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.