Adobe DTM, Session Storage, & Single Page Applications

John Simmons
Jul 16, 2018 · 6 min read

Single page applications (SPAs) are great, but it can sometimes be difficult to collect their data effectively. This is due to the fact that, as the name suggests, they do not have the typical load events (page loads, hash changes, etc.) that most analytics collection tools base their collection rules upon. Especially rules about the state of the application (i.e. what page the user is on).

Thus, it is up to the application to explicitly notify analytics tools when changes happen. Doing this may require committing custom analytics code to the application code. This is not ideal. I would like to share a strategy I have been using for data collection on single page applications: using Javascript’s sessionStorage property as a pseudo data-layer in conjunction with Adobe DTM’s “dataelementchanged” event.

Session storage is exactly what it sounds like. It is a Javascript API that allows you to store data as key/value pairs in the window.sessionStorage object. The data stored in this object is deleted at the end of a session; such as when a user closes their browser. It is a lightweight way to store temporary information that is only needed for the current session (like analytics data!) without the need to explicitly clear it like a cookie. You can view session storage data in your browser under Dev Tools > Storage > Session Storage. Session storage performance friendly and simple to use. More information on it here and here.

Some session storage data on ticketmaster.com

So how can we use session storage to help with analytics on SPAs? First let’s look at a simple SPA.

This form steps through pages with no new page loads, hash changes, or any other URL based events. A basic setup of DTM would count the initial page load as a view, but not the subsequent “pages” as the form progresses. The user’s experience vs. the analytics collected would be different.

The rule that fires on each page load

Looking in DTM debug mode in my console I can see that Adobe detected the initial page load and reported a page view, but did nothing on the subsequent pages as there was no other page load. At this point my analytics can tell that users are getting to my page, but I have no way of telling how far they get in through form or if they submit it.


In the past, I would have used DTM direct call rules here, but I don’t like them for a few reasons. First, writing direct call rules in the application couples the analytics code with application code. Say tomorrow I decided to no longer use Adobe Analytics/DTM. I would need to go through and purge my application of the direct call code. Second, direct call rules are only useful of notifying Adobe of events and data. Real websites will likely have lots of third party code such as chat vendors or marketing pixels that might find this information useful. Any javascript code on any page will have access to session storage.

I’ll start by using session storage to save page information. Here I am storing the current page and the previous page as you move through the form.

Session storage data changes as the form progresses

I will then store these session storage variables as DTM data elements. I like storing these session storage variables as custom script data elements instead of JS objects. I feel like they just work better as custom elements. They can now be used in any part of DTM.

Page custom code Data element
Accessing the data through DTM on Page 2

For my new page view rule I will use the dataelementchanged event. This event is very versatile, and in my opinion, underutilized. I think one could write an entire DTM implementation using just dataelementchanged, but I digress. With a few adjustments, this event based rule can handle everything a normal page load rule can do. Now when my session storage “page” variable changes, DTM will “notice” and fire my rule.

Listen for changes on “Page” data element
Tell Adobe Analytics to count this rule fire as a page view
Send my page data to Adobe Analytics

And Adobe does the rest…

Data Element Changed rules firing pageviews

You may notice that the Data Element Changed rule does not fire on my initial page load. I think that is because DTM library code sends a page view when it (the library code) is loaded and the creation of a data element does not count as a change to it. Please correct me if I am wrong on this.

One issue that I have encountered using this method is page refreshes and other SPA navigation. Sometimes refreshing a single page app will take you back to the first “page” with a new page load. This is the case with my form. If I am on the second “page” and refresh, I will go back to the beginning of the form and a page load rule will fire along with my data element change rule. Because of a page load and a data element change (my data elements exist and changes on the refresh), respectively.

Refreshing fires 2 page views

I can get around this in my page load rule conditions. Here I will make sure that no previous page data exists. If it doesn’t, its a fresh visit (no session storage data) and the generic page load rule will fire. If previous page data does exist, its likely a refresh or perhaps some SPA navigation and only my data element change rule will fire.

I don’t think it’s possible in DTM rules to check for an empty data element value so I do it with custom code:

If the Previous Page data element is empty or falsey, fire the page load rule

Now, if I refresh while on the second “page” of the form flow and get returned to the first page, my generic page load rule will not fire, but my data element changed on will because I still have a previous page data element.

I reloaded the first page, but my conditions prevented a double page view from firing

That’s all there is to using session storage as a source of truth for Adobe Analytics on single page apps. This example just covers page views, but could be applied to just about any event that is tricky to pick up with DTM. Just to recap I like using session storage for the following reasons:

  • I don’t have to scrape any information from the page for my data elements
  • The data in session storage is available for any application to use. For example, your chat vendor or marketing pixels
  • It keeps Adobe code out of the core application code, i.e. _satellite.track
  • Session storage is performance friendly and temporary
  • Easy to maintain and explicit for DTM admins
  • Developers/Engineers are very familiar with session storage

Thanks for reading!

John Simmons

Written by

Adobe Analytics Engineer @ Bounteous| john-simmons.net | johndavidsimmons@gmail.com

More From Medium

More from John Simmons

More from John Simmons

Top on Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade