3 steps to a Tealium Queue to avoid lost data on Single-Page Applications
How to enhance Tealium with a “utagQueue” to avoid losing data if users start clicking around before the Tealium library has loaded.
Your dev team decided that tracking should be the very last thing to load. They could be right ;). Only after all the many other scripts and libraries have been asynchronously loaded into the browser, it is your Tealium library’s turn. Tealium’s JS itself usually loads super-fast, but if it is chained behind other heavy libraries, it may still be late.
There are 2 problems here:
- If your website is a Single-Page Application (SPA), you likely use the utag_cfg_ovrd.noview flag to avoid sending the “automatic” utag.view call to execute the initial Pageview and have your application send that call (to avoid a duplicate pageview on the initial pageload). But how does your application know that Tealium is ready?
- On slow mobile connections, loading can take a long time. But until then, a lot can happen: People start clicking around because they already see the page. Your developer’s code captures these interactions and wants to execute a utag.link or utag.view call (e.g. to register the next “virtual Pageview” on a SPA), but they can’t because Tealium has not loaded completely yet. The data is lost.
When you try to send utag.view or utag.link before Tealium has downloaded or before Tealium has set up its utag object, no data will be sent and your browser will throw an uncaught error.
To avoid this, you can use this little enhancement to the basic Tealium iQ implementation:
Step 1:
Somewhere early in your code loading logic (e.g. in the <head> section), you create a utagQ.q object as well as 2 functions: utagQ.view/link:
Step 2:
Instead of utag.view and utag.link, your developers can now use utagQ.view({Data Layer Object}) and utagQ.link({Data Layer Object}). These functions simply and safely push the data into the utagQ.q and add a property “hit” which contains the type of Hit (“event” or “view”).
Example:
Step 3:
When Tealium is loaded and reaches its so-called “DOM Ready Extensions” (at this point it is ready to receive utag.view/link calls), it redefines utagQ.view and .link again to fire normal utag.view / utag.link calls. Then Tealium walks through the queue array and fires the respective utag method (view or link) for each array element. For this to happen you simply add the following code as your first “DOM Ready Extension”:
Another Option
The other common option to do this is to let your dev team handle their own queue to which they add utag.link/view payloads until the utag object is ready. From then on, they execute utag.link/view directly.
To signal your devs that Tealium is ready to receive data, you run a callback function from Tealium in your first DOM Ready Extension (something like window.tealiumReady()). Your application code then goes through their own queue and turns it into utag.view and .link calls.
But…
… you may say: “But this still does not solve the case when users click to the next page too fast on a non-SPA website!”
You are right. in that case, the queue is lost, the next page creates a new queue and we never know about what happened on that glorious previous page.
If that is a frequent case, the queue needs to be enhanced to push stuff into localStorage. Then you need to retrieve that on the next page (or whenever Tealium is finally ready). But then it gets ugly, because in that case you also need to save all the rest of the current page’s relevant context there (URL, Page Title, Referrer, and so on and you need to make sure that your requests on the next page(s) happen as if they happened on the previous page. And then that little Queue script quickly bloats up. There is a solution for this, but that would require a deep-dive into a sensible Tealium setup first which I could write about 50 other articles about. So I save that for another day.
I agree that this is nothing super-sophisticated, but the need for this has come up in a lot of (especially SPA) projects, so I thought it is time to document this somewhere. Maybe you can also benefit from it. :)