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
share, whenever an object of type
story encounters event
view, or an object of type
story encounters event
share. So trivial!
||provide object type, e.g.
||provide event, e.g.
||Universal Analytics track, category=story, action=view
||Universal Analytics track, category=story, action=share
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:
TipIf 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 macro
Abstraction, 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
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!