Acompanhamento de visualizações de página do Google Analytics com AngularJS


221

Estou configurando um novo aplicativo usando o AngularJS como front-end. Tudo no lado do cliente é feito com o pushstate HTML5 e eu gostaria de poder acompanhar minhas visualizações de página no Google Analytics.



2
angulartics está obsoleto. Use angular-google-analytics
webdev5 /

5
@ webdev5 Foi lançada uma nova versão do angulartics. Tente isso em: angulartics.github.io
Devner

Respostas:


240

Se você estiver usando ng-viewseu aplicativo Angular, poderá ouvir o $viewContentLoadedevento e enviar um evento de rastreamento ao Google Analytics.

Supondo que você configurou seu código de acompanhamento no arquivo index.html principal com um nome var _gaqe MyCtrl é o que você definiu na ng-controllerdiretiva.

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

UPDATE: para nova versão do Google Analytics, use este

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

12
FWIW que deveria ser _trackPageviewe não _trackPageView... passou 10 minutos de coçar a cabeça :)
Sajal

123
Eu usaria $rootScope.$on('$routeChangeSuccess', ...)
bearfriend

5
@DavidRivers Hm, já faz um tempo, mas só de olhar para esta resposta e meu comentário, parece que aplicá-la $rootScopegarantiria que ela não seria removida por outro evento ou alteração de DOM, e o uso routeChangeSuccessserá acionado toda vez que o a barra de localização é alterada. Em vez de sempre, você altera o modelo de origem da visualização. Isso faz sentido?
bearfriend

5
@ dg988 durante um evento $ routeChangeSuccess, você NÃO deve conhecer antecipadamente o título da página (que, por exemplo, pode ser definido dentro de um controlador após concluir o processamento de dados de um serviço RESTful). Dessa maneira, sozinho, com o URL da página, o Google Analytics rastreará um título da página anterior.
Konstantin Tarkus

43
Se você estiver usando o novo script do GA, é em $window.ga('send', 'pageview', { page: $location.path() });vez da $window._gaq...parte. Além disso, convém remover ga('send', 'pageview');do seu código GA original para evitar duplicatas quando você chegar à página pela primeira vez.
CWSpear

57

Quando uma nova visualização é carregada AngularJS, o Google Analytics não conta como um novo carregamento de página. Felizmente, existe uma maneira de informar manualmente o GA para registrar um URL como uma nova visualização de página.

_gaq.push(['_trackPageview', '<url>']); faria o trabalho, mas como vincular isso ao AngularJS?

Aqui está um serviço que você pode 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));

Ao definir seu módulo angular, inclua o módulo de análise da seguinte forma:

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

ATUALIZAÇÃO :

Você deve usar o novo código de rastreamento universal do Google Analytics com:

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

6
A outra coisa a observar aqui é que você precisa incluir o serviço "analytics" em algum lugar. Eu fiz o meu em app.run.
Nix

Isso precisaria incluir em todos os módulos ou apenas no aplicativo inicial?
Designer # #

2
@Designermonkey Deverá funcionar se você incluir apenas o módulo principal do aplicativo. Se você possui um módulo totalmente independente, embora não exija o módulo principal, pode ser necessário incluí-lo novamente. Felicidades!
Haralan Dobrev 6/11/2014

Se você estiver usando um serviço, defina suas funções com a palavra-chave "this": source . Por exemplo, dentro do serviço seria this.track = function($window.ga('send', 'pageview', {page: $location.url()});Isso permitirá que você use googleAnalytics.track();dentro de seu app.run () função
zcoon

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

8
Nota: Se você usar minimização / compilação, precisará especificar os nomes dos parâmetros:app.run(["$rootScope", "$location", function(...
dplass

Essa solução é excelente se você não deseja incluir o código GA em todos os controladores.
breez

1
Não é tão bom se você tiver um código assíncrono que altera dinamicamente o seu título; caso contrário, é ótimo.
Johan Johan

40

Apenas uma adição rápida. Se você estiver usando o novo analytics.js, então:

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

Além disso, uma dica é que o Google Analytics não será acionado no host local. Portanto, se você estiver testando no host local, use o seguinte em vez da criação padrão ( documentação completa )

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

Oh cara, obrigado. Eu estava recebendo erros estranhos, e notei que meu trecho nem tinha _gaq nele, hehe. Google bobo: atualizando seu código e tudo isso! Haha
CWSpear

3
Certifique-se de usar $windowpara acessar a janela ( gaé provável que apenas dentro do Angular esteja undefined). Além disso, convém remover ga('send', 'pageview');do seu código GA original para evitar duplicatas quando você chegar à página pela primeira vez.
CWSpear

6
Usando ui-router pode enviar páginas vistas como esta:$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { ga('send', 'pageview', { 'page': $location.path(), 'title': toState.name }); });
pherris

2
Para adicionar: se você estiver usando parâmetros de pesquisa em seu aplicativo, poderá acompanhar aqueles que usam$location.url()
Ade

2
Votei positivamente nesta resposta, já que usar .path () é melhor que .url () porque você normalmente deseja excluir parâmetros de string de consulta. Veja: Google Analytics Configuração Erro # 2: Cadeia de consulta Variáveis
frodo2975

11

Eu criei um serviço + filtro que poderia ajudar vocês com isso, e talvez também com alguns outros provedores, se você optar por adicioná-los no futuro.

Confira https://github.com/mgonto/angularytics e deixe-me saber como isso funciona para você.


10

Mesclar as respostas de wynnwu e dpineda foi o que funcionou para mim.

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

Definir o terceiro parâmetro como um objeto (em vez de apenas $ location.path ()) e usar $ routeChangeSuccess em vez de $ stateChangeSuccess fez o truque.

Espero que isto ajude.


7

Eu criei um exemplo simples no github usando a abordagem acima.

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


Eu adicionei uma correção para relatar melhor o caminho. então agora se você tem a rota do /account/:accountId caminho aka é http://somesite.com/account/123agora reportará o caminho como/account?accountId=123
IBootstrap

@IBootstrap qual é o benefício de colocar os parâmetros de rota na string de consulta?
amigos estão dizendo

@IBootstrap Tenho a mesma pergunta, qual é o benefício de colocar os parâmetros de rota na string de consulta?
Dzung Nguyen

1
Nem todas as rotas são páginas diferentes e o GA trata cada rota como uma página diferente. Ao converter a rota em string de consulta, você tem a opção de ignorar partes da string de consulta.
IBootstrap

5

A melhor maneira de fazer isso é usar o Gerenciador de tags do Google para disparar suas tags do Google Analytics com base nos ouvintes do histórico. Elas são incorporadas à interface do GTM e permitem facilmente o rastreamento nas interações HTML5 do lado do cliente.

Ative as variáveis internas do Histórico e crie um gatilho para disparar um evento com base nas alterações do histórico.


5

No seu index.html, copie e cole o snippet ga, mas remova a linhaga('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>

Eu gosto de dar o seu próprio arquivo de fábrica my-google-analytics.jscom auto-injeção:

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

Eu gosto desse material de autoinjeção :) Acima #
Sam Vloeberghs

Por curiosidade, por que você define o pagecaminho atual e o envia como a pageview? Qual é a diferença de fazer dessa maneira, em vez de apenas $window.ga('send', 'pageview', {page: $location.url()});?
Fizzix 29/02

1
Não me lembro do TBH, mas olhando para ele, eu diria que deixa flexibilidade para outras ações ou registra coisas adicionais em outros lugares, e pode ser mais preciso ao informar explicitamente o ga da página atual, para que o ga possa continuar a funcionar com precisão, em vez de APENAS registre uma visualização de página para algum URL de página "arbitrário".
31416 ilovett

Se você deseja que a análise em tempo real funcione no Google, faça "set". Por que ver a referência da documentação: developers.google.com/analytics/devguides/collection/…
fuzzysearch

'set' é recomendado para que todos os hits enviados na mesma página (como o GA Event para rastrear interações do usuário) sejam enviados com o mesmo valor do caminho da página. Nada a ver com análises em tempo real. consulte developers.google.com/analytics/devguides/collection/…
Open SEO

5

Eu encontrei a gtag()função funcionada, em vez da ga()função.

No arquivo index.html, dentro da <head>seção:

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

No código AngularJS:

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

Substitua TrackingIdpor seu próprio ID de acompanhamento.


4

Se alguém quiser implementar usando diretivas, identifique (ou crie) uma div no index.html (logo abaixo da tag body ou no mesmo nível DOM)

<div class="google-analytics"/>

e adicione o seguinte código na diretiva

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

3

Se você estiver usando o ui-router, poderá se inscrever no evento $ stateChangeSuccess assim:

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

Para um exemplo completo de trabalho, consulte esta postagem no blog


3

Use o GA 'set' para garantir que as rotas sejam selecionadas para a análise em tempo real do Google. Caso contrário, as chamadas subsequentes para o GA não serão exibidas no painel em tempo real.

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

O Google recomenda fortemente essa abordagem geralmente, em vez de passar um terceiro parâmetro em 'enviar'. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications


3

Para aqueles que usam o AngularUI Router em vez do ngRoute, pode usar o código a seguir para rastrear as visualizações de página.

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


3

Estou usando o AngluarJS no modo html5. Encontrei a seguinte solução como a mais confiável:

Use a biblioteca angular-google-analytics . Inicialize-o com 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);
  }
]);

Depois disso, adicione ouvinte em $ stateChangeSuccess 'e envie o 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
            }
        });
    }
]);

A qualquer momento, quando seu usuário for inicializado, você poderá injetar o Analytics no local e fazer uma ligação:

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

2

Estou usando o ui-router e meu código fica assim:

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

Dessa forma, eu posso rastrear estados diferentes. Talvez alguém ache útil.


1

Pessoalmente, gosto de configurar minhas análises com o URL do modelo em vez do caminho atual. Isso ocorre principalmente porque meu aplicativo possui muitos caminhos personalizados, como message/:idou profile/:id. Se eu enviasse esses caminhos, teria tantas páginas visualizadas no analytics, seria muito difícil verificar quais usuários da página estão visitando mais.

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

Agora, recebo visualizações de página limpas em minhas análises, como user-profile.htmle em message.htmlvez de muitas páginas profile/1, profile/2e profile/3. Agora posso processar relatórios para ver quantas pessoas estão visualizando perfis de usuário.

Se alguém tiver alguma objeção a respeito de por que essa é uma prática ruim dentro do analytics, eu ficaria mais do que feliz em ouvir sobre isso. Muito novo no uso do Google Analytics, por isso não tenho certeza se essa é a melhor abordagem ou não.


1

Sugiro usar a biblioteca de análise de segmentos e seguir nosso guia de início rápido angular . Você poderá rastrear visitas à página e ações de comportamento do usuário com uma única API. Se você tiver um SPA, poderá permitir que o RouterOutletcomponente manipule quando a página for renderizada e use ngOnInitpara chamar pagechamadas. O exemplo abaixo mostra uma maneira de fazer isso:

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

Eu sou o mantenedor de https://github.com/segmentio/analytics-angular . Com o segmento, você pode ativar e desativar diferentes destinos ao pressionar um botão, se estiver interessado em experimentar várias ferramentas de análise (suportamos mais de 250 destinos) sem precisar escrever nenhum código adicional. 🙂


0

Mesclando ainda mais a resposta de Pedro Lopez,

Adicionei isso ao meu módulo ngGoogleAnalytis (que reutilizo em muitos aplicativos):

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

nesse caso, tenho uma tag no meu link de índice:

  <base href="/store/">

é útil ao usar o modo html5 no angular.js v1.3

(remova a chamada da função replace () se sua tag base não terminar com uma barra /)

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

Se você está procurando o controle total do novo código de rastreamento do Google Analytics, pode usar meu próprio Angular-GA .

Ele é gadisponibilizado por injeção, facilitando o teste. Ele não faz nenhuma mágica, além de definir o caminho em cada routeChange. Você ainda precisa enviar a visualização de página como aqui.

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

Além disso, há uma diretiva gaque permite vincular várias funções de análise a eventos, como este:

<a href="#" ga="[['set', 'metric1', 10], ['send', 'event', 'player', 'play', video.id]]"></a>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.