Implementing Better Visitor Analytics
BADCamp 2018
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
ga('<command>' [, args...])
new <Command>([args...])
trackingId: | {string} | |
---|---|---|
cookieDomain: | {string} | optional |
trackerName: | {string} | optional |
fieldsObject: | {object} | optional |
ga('create', 'UA-107047227-2', 'auto');
new Create('UA-107047227-2');
plugin: | {string} | |
---|---|---|
fieldsObject: | {object} | optional |
ga('require', 'linker');
new RequirePlugin('linker');
key: | {string} | |
---|---|---|
value: | {string} | |
fieldsObject: | {object} | optional |
ga('set', 'dimension1', 'article');
new Set('dimension1', 'article');
key: | {number} | |
---|---|---|
value: | {number} | |
fieldsObject: | {object} | optional |
ga('set', 'metric1', 2);
new Set('metric1', 2);
title: | {string} | optional |
---|---|---|
location: | {string} | optional |
page: | {string} | optional |
fieldsObject: | {object} | optional |
ga('send', 'pageview');
new Pageview();
category: | {string} | |
---|---|---|
action: | {string} | |
label: | {string} | optional |
value: | {number} | optional |
fieldsObject: | {object} | optional |
ga('send', 'event', 'video', 'play', 'cats.mp4');
new Event('video', 'play', 'cats.mp4');
category: | {string} | |
---|---|---|
var: | {string} | |
value: | {number} | |
label: | {string} | optional |
fieldsObject: | {object} | optional |
ga('send', 'timing', 'resource', 'get', 100);
new Timing('resource', 'get', 100);
network: | {string} | |
---|---|---|
action: | {string} | |
target: | {string} | |
fieldsObject: | {object} | optional |
ga('send', 'social', 'twitter', 'tweet', 'articles/give-it-a-go-and-grow-your-own-herbs');
new Send('social', [
'socialNetwork' => 'twitter',
'socialAction' => 'tweet',
'socialTarget' => 'articles/give-it-a-go-and-grow-your-own-herbs'
]);
services:
umami_ga.analytics_subscriber:
class: Drupal\umami_ga\EventSubscriber\AnalyticsSubscriber
arguments: ['@current_route_match']
tags:
- { name: event_subscriber }
namespace Drupal\umami_ga\EventSubscriber;
class AnalyticsSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
AnalyticsEvents::COLLECT => [
['setNodeDimensions'],
['setTaxonomyDimensions'],
],
];
}
public function __construct(RouteMatchInterface $routeMatch) {
$this->routeMatch = $routeMatch;
}
}
public function setNodeDimensions(CollectEvent $event) {
$node = $this->routeMatch->getParameter('node')
if (empty($node)) { return; }
if (!empty($node->field_recipe_category[0]->entity)) {
$category = $node->field_recipe_category[0]->entity->name->value;
$event->addCommand(new Set('dimension1', $category));
}
if (!empty($node->field_difficulty)) {
$difficulty = $node->field_difficulty->value;
$event->addCommand(new Set('dimension2', $difficulty));
}
if ($node->bundle() == 'article') {
$username = $node->getRevisionUser()->getAccountName();
$event->addCommand(new Set('dimension3', $username));
}
}
analytics:
version: 1.x
js:
js/analytics.js: { }
dependencies:
- core/jquery
- ga/analytics
(function ($) {
$('body').on('play', 'video', function (e) {
ga('send', 'event', {
eventCategory: 'video',
eventAction: 'play',
eventLabel: $(this).data('video-id'),
});
});
})(jQuery);
function updateSomethingWithApiData() {
var dataFetchStart = new Date();
$.get('/resource')
.done(function (data) {
var dataFetchEnd = new Date();
var dataFetchDuration = dataFetchEnd.getTime() - dataFetchStart.getTime();
// Update some widget with the data.
var widgetRenderEnd = new Date();
var widgetRenderDuration = widgetRenderEnd.getTime() - dataFetchEnd.getTime();
ga('send', 'timing', 'resource', 'get', dataFetchDuration);
ga('send', 'timing', 'widget', 'update', widgetRenderDuration);
});
};
(function ($) {
jQuery('body').on('click', 'a', function (event) {
var href = $(this).attr('href');
if (
!href.match('^(\d+):\/\/')
||
href.match('^(https?):\/\/' + window.location.host)
) {
return;
}
ga('send', 'event', {
eventCategory: 'Outbound Link',
eventAction: 'click',
eventLabel: href,
transport: 'beacon'
});
});
})();
(function ($) {
$('body').on('click', 'a', function (event) {
var href = $(this).attr('href');
if (!href.match('^(\d+):\/\/') || href.match('^(https?):\/\/' + window.location.host)) {
return;
}
event.preventDefault();
ga('send', 'event', {
eventCategory: 'Outbound Link',
eventAction: 'click',
eventLabel: href,
hitCallback: function() {
document.location = href;
}
});
});
})(jQuery);