Skip to content

Instantly share code, notes, and snippets.

@cougrimes
Last active September 10, 2020 17:03
Show Gist options
  • Save cougrimes/13cd13d9bb7bdf6ff74b6d494c0ba592 to your computer and use it in GitHub Desktop.
Save cougrimes/13cd13d9bb7bdf6ff74b6d494c0ba592 to your computer and use it in GitHub Desktop.
I got frustrated by the lack of more intuitive single-page app tracking in Tealium and wrote a hacky workaround. Use at your own discretion.
/* Welcome to lib-singlepageapp.js! This script is meant to handle using single-page
applications (SPAs) for Tealium when you do not have direct access to Angular, Vue,
React, etc. for making modifications. This allows us to get around limitations of
utag.view(). The trigger in this case is a global event listener that evaluates
any time there is a click, HTML5 history API replacement, load event, or DOMContentLoaded
event. If a new URL is populated via the history API, we'll treat that as a "pageview".
Note in this case that I have defined a UDO variable of page. This variable is then mapped
to anything requiring a page URL. For example, in GA I have this variable mapped to
config.page_location so it acts like a native page URL view.*/
// Set up our utag configuration to treat everything as noview until we tell it otherwise
window.utag_cfg_ovrd = window.utag_cfg_ovrd || {};
window.utag_cfg_ovrd.noview = true;
/* Listen for changes on the URL itself once there is a click as our trigger for recording "pageviews".
We'll first reset our utag native DOM data to be what we'd expect from the faux URL. This method is
ugly as sin, but Internet Explorer is why we can't have nice things. :( From there, we'll execute a
utag.view() command. */
let url = window.location.href;
var utagUpdate = function utagUpdate() {
utag.view({
"page": document.URL
"dom.url": document.URL,
"dom.domain": document.location.hostname,
"dom.hash": document.location.hash,
"dom.pathname": document.location.pathname,
"dom.query_string": document.location.search,
"dom.referrer": document.referrer,
"dom.title": document.title
});
};
/* Note that here we've put a 500ms delay to try to account for delays within the app.
This is far from ideal (the ideal being hooking into something like router or
$location, but then there'd be no need for this, eh?) but is a hacky workaround.
The best possible way to handle this if you don't have access to the codebase is
to request a monitorable DOM change (e.g., title tag change or some key component)
to trigger with instead. */
['click', 'popstate', 'pageshow', 'load', 'DOMContentLoaded'].forEach(evt =>
window.addEventListener(evt, function() {
requestAnimationFrame(() => {
if (url !== location.href) {
setTimeout(utagUpdate, 500);
}
url = location.href;
});
}, true)
);
@cougrimes
Copy link
Author

For Angular apps, if you find this working a little less than ideal, you can always do something similar to

utag.view({ "page": $location.url() });

in order to address some of the same issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment