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

dj2
źródło
Spróbuj angulartics luisfarzati.github.io/angulartics
David
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() });
  });
}
dj2
źródło
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()});
Haralan Dobrev
źródło
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());
    });
});
dpineda
źródło
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'});
wynnwu
źródło
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
11

Stworzyłem usługę + filtr, który może wam w tym pomóc, a może także u niektórych innych dostawców, jeśli zdecydujecie się je dodać w przyszłości.

Sprawdź https://github.com/mgonto/angularytics i daj mi znać, jak to działa.

mgonto
źródło
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.

Pedro Lopez
źródło
7

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

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

IBootstrap
źródło
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.

użytkownik2236721
źródło
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
    }
  ]);
ilovett
źródło
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.

Brent Washburne
źródło
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()]);
      });
    }
  };
});
coderman
źródło
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

Jason
źródło
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

wyszukiwanie rozmyte
źródło
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');
    });
});
Kevin M.
źródło
3

Deweloperzy tworzący pojedynczą stronę Aplikacje mogą korzystać z AutoTrack , która zawiera urlChangeTracker plugin, który obsługuje wszystkie z ważnych względów wymienionych w niniejszym przewodniku dla Ciebie. Zobacz dokumentację AUTOTRACK eksploatacji i instalacji instrukcji.

Abou-Emish
źródło
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);
maleta
źródło
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.

Miha Eržen
źródło
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.

Fizzix
źródło
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. 🙂

William
źródło
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()
          });
        }
      );
    }
  ]);
Felipe Sousa Iketani
źródło
-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>
Rafał Lindemann
źródło