Google Analytics is great. I love it! People at my company love it! It tells you so many things about how your audience uses your app. But once your feet are deep into the analytics game, your application will probably end up with a bunch of clunky analytics tracking code as below:
Don’t get me wrong, the Google Analytics API is in no way bad, but the direct application of ‘analytics tracking’ may backfire you in the future, let’s say when you switch to another provider, or when you simply want to change the name of a category/action. This calls for a layer of abstraction to future proof your tracking methods.
Coincidentally (or not!), Google Tag Manager comes into the picture to help the abstraction of analytics tracking in a (not so) intuitive way. The idea behind Google Tag Manager is excellent, although it takes even an experienced engineer a while to logically put all its concepts in the correct place. That may explain why it does not get as popular as Google Analytics.
Google Tag Manager explained
Let’s take an example to explain how things work in Google Tag Manager. Assuming you want to repeat the Google Analytics logic above: send a request to Google Analytics, with category story
, action view
or share
, whenever an object of type story
encounters event view
, or an object of type story
encounters event share
. So trivial!
In ‘Google Tag Manager language’, using its 3 main concepts: macro, rule and tag, this can be specified as follows:
macro object_type |
provide object type, e.g. story |
macro event |
provide event, e.g. view or share |
rule any story view |
object_type =story & event =view [& object_id =*] |
rule any story share |
object_type =story & event =share [& object_id =*] |
tag track story view |
Universal Analytics track, category=story, action=view when any story view is triggered |
tag track story share |
Universal Analytics track, category=story, action=share when any story share is triggered |
In simple words, a tag connects to your analytics service, whenever rules that compare data sent from your app - retrieved via macros - are matched.
With this setup, an equivalent logic to the original Google Analytics example is as follows:
Tip
If you have multiple Google Analytics trackers, you can also send the tracker ID you want to communicate with as a data variable that can be retrieved via macroAbstraction, Abtraction, Abstraction!
So now we have made some progress, converting our Google Analytics logic into Google Tag Manager logic, adding tons of complexity. But for what?
At a glance, the two code blocks before and after look almost identical. But looking closer, you can notice that we have managed to put an abstraction layer between our ‘interaction definition’ and Google Analytics ‘event definition’.
We don’t push an event to the tracking service anymore. We push our data model and its interaction to a ‘data sink’, that will decide how this information will be processed and sent to the tracking service. In Google Tag Manager, ‘data model’ is defined in the form of DataLayer
.
If we generalize our data model and its interaction definition, treating anything that can be interacted with as a Trackable
object, then we can just simply dump any interaction with a Trackable
to Google Tag Manager, or an in-house data sink, delaying the decision of what to track for another day, and move forward with the project, without having to worry about fixing the code later to change tracking logic.
Using the above Trackable
interface and the fluent-API Analytic.Builder
class, one can dump interaction data to Google Tag Manager as follows:
Of course, generalizing things and introducing abstraction layers will make things less flexible for some special cases. But in general, I always find that with some smart combinations of Google Tag Manager’s tag and rule, the same can be achieved without losing the generality. And even better: the real tracking logic is now essentially broken free from our app!