Я создаю новое приложение, использующее AngularJS в качестве интерфейса. Все на стороне клиента выполняется с помощью pushstate HTML5, и я хотел бы отслеживать просмотры своих страниц в Google Analytics.
Если вы используете ng-view
в своем приложении Angular, вы можете прослушать событие $viewContentLoaded
и нажать отслеживание в Google Analytics.
Предполагая, что вы настроили код отслеживания в основном файле index.html с именем var _gaq
, а MyCtrl - это то, что вы определили в директиве ng-controller
.
function MyCtrl($scope, $location, $window) {
$scope.$on('$viewContentLoaded', function(event) {
$window._gaq.push(['_trackPageView', $location.url()]);
});
}
UPDATE: для новой версии google-analytics используйте этот
function MyCtrl($scope, $location, $window) {
$scope.$on('$viewContentLoaded', function(event) {
$window.ga('send', 'pageview', { page: $location.url() });
});
}
_trackPageview
а не _trackPageView
... потратил 10 минут царапин головы :)
$rootScope.$on('$routeChangeSuccess', ...)
Когда новое представление загружается в AngularJS
, Google Analytics не считает его новой загрузкой страницы. К счастью, есть способ вручную сообщить GA для регистрации URL-адреса в качестве нового просмотра страницы.
_gaq.push(['_trackPageview', '<url>']);
выполнит эту работу, но как связать это с AngularJS?
Вот сервис, который вы можете использовать:
(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));
Когда вы определяете свой angular модуль, включите модуль аналитики следующим образом:
angular.module('myappname', ['analytics']);
UPDATE
Вы должны использовать новый код отслеживания Universal Analytics с помощью:
$window.ga('send', 'pageview', {page: $location.url()});
app.run(function ($rootScope, $location) {
$rootScope.$on('$routeChangeSuccess', function(){
ga('send', 'pageview', $location.path());
});
});
app.run(["$rootScope", "$location", function(...
Просто быстрое дополнение. Если вы используете новую analytics.js, то:
var track = function() {
ga('send', 'pageview', {'page': $location.path()});
};
Кроме того, один совет: Google Analytics не будет запускаться на localhost. Поэтому, если вы тестируете на localhost, используйте вместо созданной по умолчанию create (полную документацию)
ga('create', 'UA-XXXX-Y', {'cookieDomain': 'none'});
$window
для доступа к окну ( ga
внутри Angular, скорее всего, не undefined
). Также вы можете удалить ga('send', 'pageview');
от вашего исходного кода GA, чтобы предотвратить дубликаты при первом попадании на страницу.
Я создал фильтр службы +, который может помочь вам с этим, а может быть, и с некоторыми другими провайдерами, если вы захотите добавить их в будущем.
Отъезд https://github.com/mgonto/angularytics и дайте мне знать, как это работает для вас.
Объединение ответов wynnwu и 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()
});
});
}
]);
Установка третьего параметра в качестве объекта (вместо $location.path()) и использование $routeChangeSuccess вместо $stateChangeSuccess сделал трюк.
Надеюсь, что это поможет.
Я создал простой пример для github, используя вышеупомянутый подход.
/account/:accountId
aka path is http://somesite.com/account/123
он теперь сообщит путь как /account?accountId=123
Лучший способ сделать это - использовать Диспетчер тегов Google, чтобы запускать теги Google Analytics на основе прослушивателей истории. Они встроены в интерфейс GTM и легко позволяют отслеживать взаимодействие HTML5 на стороне клиента.
Включите встроенные переменные истории и создайте триггер для запуска события на основе изменений истории.
Если кто-то хочет реализовать с помощью директив, тогда определите (или создайте) div в index.html(просто под тегом body или на том же уровне DOM)
<div class="google-analytics"/>
а затем добавьте следующий код в директиву
myApp.directive('googleAnalytics', function ( $location, $window ) {
return {
scope: true,
link: function (scope) {
scope.$on( '$routeChangeSuccess', function () {
$window._gaq.push(['_trackPageview', $location.path()]);
});
}
};
});
Я использую AngluarJS в режиме html5. Я нашел следующее решение наиболее надежным:
Используйте angular-google-analytics библиотеку. Инициализируйте его чем-то вроде:
//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);
}
]);
После этого добавьте прослушиватель в $stateChangeSuccess 'и отправьте событие 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
}
});
}
]);
В любой момент, когда у вас активирован ваш пользователь, вы можете добавить туда Analytics и позвонить:
Analytics.set('&uid', user.id);
Используйте GA 'set', чтобы гарантировать, что маршруты собираются для аналитики в реальном времени Google. В противном случае последующие вызовы в GA не будут отображаться на панели реального времени.
$scope.$on('$routeChangeSuccess', function() {
$window.ga('set', 'page', $location.url());
$window.ga('send', 'pageview');
});
Google настоятельно рекомендует этот подход вообще вместо того, чтобы передать третий параметр в 'send'. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
Если вы используете ui-router, вы можете подписаться на событие $stateChangeSuccess следующим образом:
$rootScope.$on('$stateChangeSuccess', function (event) {
$window.ga('send', 'pageview', $location.path());
});
Для полного рабочего примера см. этот пост в блоге
В index.html
скопируйте и вставьте фрагмент ga, но удалите строку ga('send', 'pageview');
<!-- Google Analytics: change UA-XXXXX-X to be your site 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>
Мне нравится присваивать ему собственный factory файл my-google-analytics.js
с самостоятельной инъекцией:
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
}
]);
page
с текущим путем, а затем отправляете ее как pageview
? Какая разница в том, чтобы делать это таким образом, вместо того, чтобы просто $window.ga('send', 'pageview', {page: $location.url()});
?
Я использую ui-router, и мой код выглядит следующим образом:
$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);
});
Таким образом, я могу отслеживать разные состояния. Может быть, кто-то найдет это полезным.
Разработчики, создающие Single Pages Applications, могут использовать autotrack, который включает urlChangeTracker, который обрабатывает все важные соображения, перечисленные в этом руководстве для вас. См. Документацию autotrack для инструкций по использованию и установке.
Для тех, кто использует AngularUI Router вместо ngRoute, вы можете использовать следующий код для отслеживания просмотров страниц.
app.run(function ($rootScope) {
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
ga('set', 'page', toState.url);
ga('send', 'pageview');
});
});
Мне лично нравится настраивать свою аналитику с URL-адресом шаблона вместо текущего. Это связано главным образом с тем, что мое приложение имеет множество настраиваемых путей, таких как message/:id
или profile/:id
. Если бы я отправил эти пути, у меня было бы так много страниц, которые просматривались бы в аналитике, было бы слишком сложно проверить, какие пользователи страниц посещают больше всего.
$rootScope.$on('$viewContentLoaded', function(event) {
$window.ga('send', 'pageview', {
page: $route.current.templateUrl.replace("views", "")
});
});
Теперь я получаю чистые просмотры страниц в своих аналитиках, таких как user-profile.html
и message.html
, а не во всех страницах profile/1
, profile/2
и profile/3
. Теперь я могу обрабатывать отчеты, чтобы узнать, сколько людей просматривают профили пользователей.
Если у кого-то есть возражения против того, что это плохая практика в аналитике, я был бы более чем счастлив услышать об этом. Совершенно новый подход к использованию Google Analytics, поэтому не слишком уверен, что это лучший подход или нет.
Объединив еще больше с ответом Педро Лопеса,
Я добавил это в свой модуль ngGoogleAnalytis (который я повторно использую во многих приложениях):
var base = $('base').attr('href').replace(/\/$/, "");
В этом случае у меня есть тег в моей индексной ссылке:
<base href="/store/">
полезно при использовании режима html5 на angular.js v1.3
(удалите вызов функции replace(), если ваш базовый тег не заканчивается косой чертой /)
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()
});
}
);
}
]);
Если вы ищете полный контроль над новым кодом отслеживания Google Analytics, вы можете использовать мой собственный Angular-GA.
Он делает ga
доступным через инъекцию, поэтому его легко тестировать. Он не делает никакой магии, кроме установки пути на каждом маршруте. Вам все равно нужно отправить просмотр страницы, как здесь.
app.run(function ($rootScope, $location, ga) {
$rootScope.$on('$routeChangeSuccess', function(){
ga('send', 'pageview');
});
});
Дополнительно существует директива ga
, которая позволяет связать несколько функций аналитики с событиями, например:
<a href="#" ga="[['set', 'metric1', 10], ['send', 'event', 'player', 'play', video.id]]"></a>