Seguimiento de vistas de página de Google Analytics con AngularJS

Respuestas:

240

Si está utilizando ng-viewsu aplicación Angular, puede escuchar el $viewContentLoadedevento y enviar un evento de seguimiento a Google Analytics.

Suponiendo que haya configurado su código de seguimiento en su archivo index.html principal con un nombre var _gaqy MyCtrl es lo que ha definido en la ng-controllerdirectiva.

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

ACTUALIZACIÓN: para la nueva versión de google-analytics use esta

function MyCtrl($scope, $location, $window) {
  $scope.$on('$viewContentLoaded', function(event) {
    $window.ga('send', 'pageview', { page: $location.url() });
  });
}
dj2
fuente
12
FWIW debería ser _trackPageviewy no _trackPageView... pasó 10 minutos rascándose la cabeza :)
sajal
123
Yo usaría $rootScope.$on('$routeChangeSuccess', ...)
bearfriend
55
@DavidRivers Hm, ha pasado un tiempo, pero solo al mirar esta respuesta y mi comentario, parece que aplicarlo $rootScopegarantizaría que no se eliminará por algún otro evento o cambio de DOM, y el uso routeChangeSuccessse disparará cada vez que la barra de ubicación cambia, en vez de cambiar la plantilla de origen de la vista. ¿Tiene sentido?
bearfriend
55
@ dg988 durante un evento $ routeChangeSuccess, es posible que NO conozca por adelantado el título de la página (que, por ejemplo, podría establecerse dentro de un controlador después de que termine de procesar los datos de un servicio RESTful). De esta manera, solo con la URL de la página, Google Analytics rastreará un título de la página anterior.
Konstantin Tarkus
43
Si está utilizando el nuevo script de GA, es en $window.ga('send', 'pageview', { page: $location.path() });lugar de la $window._gaq...parte. Además, es posible que desee eliminar ga('send', 'pageview');su código GA original para evitar duplicados cuando aterrice por primera vez en una página.
CWSpear
57

Cuando se carga una nueva vista AngularJS, Google Analytics no la cuenta como una nueva carga de página. Afortunadamente, hay una manera de decirle manualmente a GA que registre una URL como una nueva página vista.

_gaq.push(['_trackPageview', '<url>']); haría el trabajo, pero ¿cómo vincular eso con AngularJS?

Aquí hay un servicio que podría usar:

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

Cuando defina su módulo angular, incluya el módulo de análisis de la siguiente manera:

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

ACTUALIZACIÓN :

Debe usar el nuevo código de seguimiento de Universal Google Analytics con:

$window.ga('send', 'pageview', {page: $location.url()});
Haralan Dobrev
fuente
66
La otra cosa a tener en cuenta aquí es que debe incluir el servicio de "análisis" en alguna parte. Hice el mío en app.run.
Nix
¿Tendría que incluir esto en cada módulo, o solo en la aplicación inicial?
designermonkey
2
@Designermonkey Debería funcionar si incluye solo en su módulo de aplicación principal. Si tiene un módulo totalmente independiente que no requiere su módulo principal, es posible que deba incluirlo nuevamente. ¡Salud!
Haralan Dobrev
Si está utilizando un servicio, debe definir sus funciones con la palabra clave "this": fuente . Por ejemplo, dentro del servicio sería this.track = function($window.ga('send', 'pageview', {page: $location.url()});Esto le permitirá utilizar googleAnalytics.track();dentro de su app.run () la función
zcoon
48
app.run(function ($rootScope, $location) {
    $rootScope.$on('$routeChangeSuccess', function(){
        ga('send', 'pageview', $location.path());
    });
});
dpineda
fuente
8
Nota: Si utiliza minimización / compilación, debe especificar los nombres de los parámetros:app.run(["$rootScope", "$location", function(...
dplass
Esta solución es excelente si no desea incluir el código GA en cada controlador.
breez
1
No es tan bueno si tiene un código asíncrono que cambia dinámicamente su título, de lo contrario, es genial.
Johan
40

Solo una adición rápida. Si está utilizando el nuevo analytics.js, entonces:

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

Además, un consejo es que google analytics no se activará en localhost. Entonces, si está probando en localhost, use lo siguiente en lugar de la creación predeterminada ( documentación completa )

ga('create', 'UA-XXXX-Y', {'cookieDomain': 'none'});
wynnwu
fuente
Oh hombre, gracias. Estaba recibiendo errores extraños, y noté que mi fragmento ni siquiera tenía _gaq, jeje. Google tonto: ¡actualizando su código y todo eso! Jaja.
CWSpear
3
Asegúrese de usar $windowpara acceder a la ventana ( gaes muy probable que solo dentro de Angular lo sea undefined). Además, es posible que desee eliminar ga('send', 'pageview');su código GA original para evitar duplicados cuando aterrice por primera vez en una página.
CWSpear
66
Usando ui-router puede enviar vistas de página como esta:$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { ga('send', 'pageview', { 'page': $location.path(), 'title': toState.name }); });
pherris
2
Para agregar: Si está usando parámetros de búsqueda en su aplicación, puede rastrearlos usando$location.url()
Ade
2
Voté esta respuesta ya que usar .path () es mejor que .url () porque normalmente quieres excluir los parámetros de cadena de consulta. Consulte: Error de configuración de Google Analytics n. ° 2: Variables de cadena de consulta
frodo2975
11

Creé un servicio + filtro que podría ayudarlos con esto, y tal vez también con algunos otros proveedores si eligen agregarlos en el futuro.

Visite https://github.com/mgonto/angularytics y dígame cómo funciona esto para usted.

mgonto
fuente
10

Combinar las respuestas de wynnwu y dpineda fue lo que funcionó para mí.

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

Establecer el tercer parámetro como un objeto (en lugar de solo $ location.path ()) y usar $ routeChangeSuccess en lugar de $ stateChangeSuccess hizo el truco.

Espero que esto ayude.

Pedro Lopez
fuente
7

He creado un ejemplo simple en github usando el enfoque anterior.

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

IBootstrap
fuente
Agregué una solución para informar mejor la ruta. así que ahora si tienes la ruta de la ruta /account/:accountId aka http://somesite.com/account/123, ahora informará la ruta como/account?accountId=123
IBootstrap el
@IBootstrap, ¿cuál es el beneficio de poner los parámetros de ruta en la cadena de consulta?
Pavel Nikolov
@IBootstrap Tengo la misma pregunta, ¿cuál es el beneficio de poner los parámetros de ruta en la cadena de consulta?
Dzung Nguyen
1
No todas las rutas son páginas diferentes y GA trata cada ruta como una página diferente. Al convertir la ruta a una cadena de consulta, tiene la opción de ignorar partes de la cadena de consulta.
IBootstrap
5

La mejor manera de hacerlo es usar el Administrador de etiquetas de Google para activar sus etiquetas de Google Analytics en función de los oyentes del historial. Estos están integrados en la interfaz GTM y permiten fácilmente el seguimiento de las interacciones HTML5 del lado del cliente.

Habilite las variables de historial incorporadas y cree un desencadenador para activar un evento en función de los cambios del historial.

usuario2236721
fuente
5

En su index.html, copie y pegue el fragmento ga pero elimine la líneaga('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>

Me gusta darle su propio archivo de fábrica my-google-analytics.jscon autoinyección:

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
fuente
Me gustan esas cosas de autoinyección :) Arriba
Sam Vloeberghs
Solo por curiosidad, ¿por qué configura la pageruta actual y luego la envía como pageview? ¿Cuál es la diferencia de hacerlo así en lugar de solo $window.ga('send', 'pageview', {page: $location.url()});?
Fizzix
1
No puedo recordar TBH, pero al mirarlo diría que deja flexibilidad para otras acciones o registra cosas adicionales en otro lugar, y puede ser más preciso al decir explícitamente a ga de la página actual, para que ga pueda continuar funcionando con precisión, en lugar de SOLO registrando una página vista para alguna url de página "arbitraria".
ilovett
Si desea que los análisis en tiempo real funcionen en Google, debe "configurar". Para saber por qué consulte la referencia de documentación: developers.google.com/analytics/devguides/collection/…
fuzzysearch
'set' se recomienda para que cada hit que se envíe en la misma página (como GA Event para rastrear las interacciones del usuario) se envíe con el mismo valor de ruta de página. Nada que ver con el análisis en tiempo real. ver developers.google.com/analytics/devguides/collection/…
Abrir SEO
5

Encontré que la gtag()función funcionaba, en lugar de la ga()función.

En el archivo index.html, dentro de la <head>sección:

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

En el código AngularJS:

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

Reemplace TrackingIdcon su propia identificación de seguimiento.

Brent Washburne
fuente
4

Si alguien quiere implementar usando directivas, identifique (o cree) un div en index.html (justo debajo de la etiqueta del cuerpo, o en el mismo nivel de DOM)

<div class="google-analytics"/>

y luego agregue el siguiente código en la directiva

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

Si está utilizando ui-router, puede suscribirse al evento $ stateChangeSuccess de esta manera:

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

Para un ejemplo de trabajo completo, vea esta publicación de blog

Jason
fuente
3

Use GA 'set' para asegurarse de que se seleccionen las rutas para el análisis en tiempo real de Google. De lo contrario, las llamadas posteriores a GA no se mostrarán en el panel en tiempo real.

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

Google recomienda encarecidamente este enfoque en general en lugar de pasar un tercer parámetro en 'enviar'. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications

Búsqueda borrosa
fuente
3

Para aquellos de ustedes que usan AngularUI Router en lugar de ngRoute, pueden usar el siguiente código para rastrear las visitas a la página.

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

Estoy usando AngluarJS en modo html5. Encontré la siguiente solución como la más confiable:

Utilice la biblioteca angular-google-analytics . Inicialízalo con algo como:

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

Después de eso, agregue escucha en $ stateChangeSuccess 'y envíe el evento 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
            }
        });
    }
]);

En cualquier momento, cuando haya inicializado a su usuario, puede inyectar Analytics allí y hacer una llamada:

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

Estoy usando ui-router y mi código se ve así:

$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 esta manera puedo rastrear diferentes estados. Quizás alguien lo encuentre útil.

Miha Eržen
fuente
1

Personalmente, me gusta configurar mis análisis con la URL de la plantilla en lugar de la ruta actual. Esto se debe principalmente a que mi aplicación tiene muchas rutas personalizadas como message/:ido profile/:id. Si tuviera que enviar estas rutas, vería tantas páginas dentro de análisis que sería demasiado difícil verificar qué página visitan más los usuarios.

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

Ahora obtengo vistas de página limpias dentro de mi análisis, como user-profile.htmly en message.htmllugar de muchas páginas profile/1, profile/2yprofile/3 . Ahora puedo procesar informes para ver cuántas personas están viendo los perfiles de usuario.

Si alguien tiene alguna objeción de por qué esta es una mala práctica dentro de la analítica, me encantaría saberlo. Muy nuevo en el uso de Google Analytics, así que no estoy muy seguro de si este es el mejor enfoque o no.

Fizzix
fuente
1

Sugiero usar la biblioteca de análisis de segmentos y seguir nuestra guía de inicio rápido angular . Podrá realizar un seguimiento de las visitas a la página y las acciones de comportamiento del usuario con una única API. Si tiene un SPA, puede permitir que el RouterOutletcomponente maneje cuando la página se procesa y usar ngOnInitpara invocar pagellamadas. El siguiente ejemplo muestra una forma de hacer esto:

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

Soy el encargado de mantener https://github.com/segmentio/analytics-angular . Con Segment, podrá activar y desactivar diferentes destinos con solo presionar un interruptor si está interesado en probar varias herramientas de análisis (admitimos más de 250 destinos) sin tener que escribir ningún código adicional. 🙂

Guillermo
fuente
0

Fusionándose aún más con la respuesta de Pedro López,

Agregué esto a mi módulo ngGoogleAnalytis (que reutilizo en muchas aplicaciones):

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

en este caso, tengo una etiqueta en mi enlace de índice:

  <base href="/store/">

es útil cuando se usa el modo html5 en angular.js v1.3

(elimine la llamada a la función replace () si su etiqueta base no termina con una barra inclinada /)

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

Si está buscando el control total del nuevo código de seguimiento de Google Analytics, puede usar mi propio Angular-GA .

Se pone a gadisposición mediante inyección, por lo que es fácil de probar. No hace ninguna magia, aparte de establecer el camino en cada ruta Cambiar. Todavía tiene que enviar la página vista como aquí.

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

Además, hay una directiva gaque permite vincular múltiples funciones analíticas a eventos, como esta:

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