For some reason, I have lately been exposed to a lot of Angular Single-Page Applications.
As you probably know, SPAs are the mortal enemy of the analyst, or at least the implementer, but as you also know, we must overcome our fears to grow. Or something like that.
While this sounds empowering to some, and downright cheesy to others, I am pretty neutral about how I describe what was an internal conflict: should I learn about Angular? To the point where I could give Angular developers some helpful assistance regarding Analytics? Face the enemy? Or shy away from it? Leave them alone, out there in the cold, dark?
Actually, there was a third way, a really simple way, too: angulartics2
Some good folk had built a vendor-independent framework that comes with a concept of “Providers” for all sorts of Analytics Solutions out there.
Launch & angulartics2
When I started writing about this, angulartics2 had a “provider” for Adobe Analytics, but none for DTM or Launch. A good start, but we’re in 2019 now, and noone should deploy any tools without a tag manager.
So my first step was to build a provider for Launch, by Adobe, and get it accepted into angulartics2.
I am happy to report that with some unexpected help — thank you, Arjan & Ralph — I succeeded. Version 7.2 of angulartics2 (which was btw the 100th release), includes a basic provider for Launch, by Adobe, written by yours truly.
As of version 7.2 of angulartics2, adding tracking of route changes with Launch into a standard Angular2 SPA is almost ridiculously easy.
The angulartics2 framework knows two different ways of tracking:
eventTrack. Most providers simply pass those through as “normal” tracking, or event/goal tracking, respectively.
I built the provider for Launch to call
_satellite.track() in both cases, but with different IDs. These are currently hard-coded.
pageTrack out of angulartics2 will call
_satellite.track('pageTrack');, and an
eventTrack will call
_satellite.track('eventTrack');. There is a bit of payload, too, but not a lot. I guess there’s room for improvement…
This is not a long article, because at this point, we’re essentially done.
If you create two (always 2!) Rules in Launch, both listening to the “pageTrack” Direct-call Event, one setting pageName from the payload send on the Event, the other firing the beacon (always split those up!), you have what all other “Basic Tracking” articles had.
Ridiculously easy, right?
I don’t think the provider I wrote is finished.
Just like I keep writing in the “Basic Tracking” articles, tracking only the pageName is simply not good enough. We are all better than that.
The additional data could live in a data layer, I guess, where it could easily be read using Data Elements.
It’s a good approach, independent of tool, function, or purpose of the data, and it should be the way we all handle data.
If you can’t do that, though, angulartics2 comes with a mechanism to handle additional data itself. A lot of the other providers come with two calls (
setUserProperties()), which pass data into an internal object. And some other providers track that data along with every call.
As of v7.2.4, the provider for Launch passes that data into both
pageTrack as well as
The people who currently work on the provider for
piwik Matomo have started implementing specific calls (e.g. ‘trackEcommerceOrder’), and the provider for Adobe Analytics even has a ‘setPageName()’ method.
I’d like there to be some standard, of course. Would be silly if each provider implemented their own thing.
For now, if you want additional data on a page load, use
or put it into a data layer.
As long as you do that inside any of the “early” lifecycle methods (like
ngAfterViewInit), the data will be available before the call to
pageTrack happens, and it will therefore be available for tracking.
Always more after that
Tracking of events or activities is different, of course.
With angulartics2, you can either declare tracking and data in the HTML templates, or you can program it right into the Typescript code using the
The method takes a ‘properties’ object, which can contain anything, really. Most providers (including the one for Launch) simply pass the data through, and so in Launch, you have access to all that data.
Again, a data layer helps, too.
You can even forego tracking of events in HTML or Typescript completely! Instead, add an event object to the data layer each time something important happens, and listen to data layer changes using Launch.
The big advantage: no dependencies on Launch or even angulartics2 in your code.
Sending a Custom Event instead of writing into a data layer would work the same.
I have so far not picked my favourite, but it is good to know there are options.
Sounds like I will have to write a more in-depth article at some point. And that means I must learn at least a little bit about writing an Angular SPA.