Chal­lenges Sur­round­ing Ana­lyt­ics Tag­ging
maigi / 123RF Stock PhotoI am often asked if Tag­Man­ager can be used to tag a par­tic­u­lar site.  It seems easy.  If we can get a ref­er­ence to the JavaScript on all the pages, is it pos­si­ble to setup all the data col­lec­tion for the entire site from that ref­er­ence?  It’s an inter­est­ing propo­si­tion.  Some cus­tomers com­ment that Site­Cat­a­lyst and the entire Dig­i­tal Mar­ket­ing Suite’s imple­men­ta­tion can be painful.  Some cus­tomers remark that it can be cum­ber­some and often involves a huge invest­ment of time and effort for sim­ple changes.  For­tu­nately, there are a hand­ful of tools that have been put in place to address these issues.  The intro­duc­tion of new fea­tures such as pro­cess­ing rules and con­text data vari­ables make imple­ment­ing data col­lec­tion much easier.

Enter Tag Man­ager
Tag­Man­ager is prob­a­bly the most pow­er­ful com­pli­ment to that toolset, but still the stan­dard way of sur­fac­ing data on the page through JavaScript cre­ates a higher bar of imple­ment­ing.  Often when data is sur­faced on the page in JavaScript rather than HTML it requires a devel­oper to do the work, as well as a higher level of accep­tance test­ing than is required with HTML.  HTML doesn’t exe­cute so the risks are inher­ently lower.  This got me think­ing:  what if we used only HTML for tag­ging?  After all, the Doc­u­ment Object Model is based on Object-Oriented pro­gram­ming par­a­digms.  It should be pos­si­ble to make the D in DOM respon­si­ble for its own data.

The Chal­lenge: JavaScript-Free Tag­ging
So as a chal­lenge, I decided to assem­ble a brand new, pie-in-the-sky approach to tag­ging.  What would JavaScript-free tag­ging look like?  How would we approach it from a devel­op­ment aspect and make it sup­port­able and respon­sive to mar­ket­ing needs?  Here are the require­ments for this challenge:

  1. The imple­men­ta­tion should be loosely cou­pled.  If an ele­ment is removed from the page acci­den­tally it shouldn’t cre­ate a JavaScript error.
  2. The page should effec­tively “lis­ten” for data.  This includes respond­ing to event-triggered tag­ging as well and page-driven tagging.
  3. The order of oper­a­tion should be irrel­e­vant.  That is, a JavaScript file declared at the top page ver­sus the bot­tom of the page should make no dif­fer­ence.  In the end we need data regard­less of the exe­cu­tion order.
  4. Data should only be and always be HTML.

An Exam­ple:
Let’s begin with an exam­ple of a sim­ple HTML page. On any page I have lots of data. Let’s sup­pose we are dis­cussing a prod­uct page that has a pic­ture of the prod­uct with a name as well as a cart icon some­where that indi­cates the num­ber of items in the cart among numer­ous other items.  Bottom-line:  there’s an incred­i­ble amount of data on every page before ever tag­ging any­thing.  All of this data can poten­tially be used to pop­u­late tag­ging vari­ables.  You can write a sim­ple JavaScript line to pull the inner­HTML from the </h1> tag and instantly you have a usable page­Name. But what hap­pens when the web devel­oper changes the </h1> tag to </h2>?  Just as quickly as you cre­ated a solu­tion, the change has caused it to stop functioning!

Instead of look­ing for par­tic­u­lar HTML ele­ments, let’s instead lever­age the class attribute to indi­cate that the </h1> or </h2> ele­ments are data.  In this way, we can look for an iden­ti­fier such as “ATM” to indi­cate that the item is data and we don’t need to rely on the ele­ment type, which may change over time.

For exam­ple, with the page below we can use sim­ple JavaScript (document.getElementsByClassName) to grab all the data points.  Easy right?

<html>
<body>
<h1 class="ATM">My Title</h1>
<div>Widget<div>
</body>
<html>

So, how do we know what to do with that data?  Does the <h1> class go into page name?  Does the <div> class go into the prod­ucts vari­able?  Ok, so it’s not quite that sim­ple. We have a few more things to do.  Since we know that the two ele­ments above con­tain data, let’s now fig­ure out how to under­stand where the data should live.  The “id” attribute has a sim­i­lar func­tion.  The vari­able name (prop1, eVar4, etc.) should be unique to the page.  In our exam­ple then, let’s add an id.

<html>
<body>
<h1 id="title">My Title</h1>
<div id="products" class="ATM">Widget<div>
</body>
<html>

We now have 2 data ele­ments that we will use to col­lect data: title and prod­ucts.  Effec­tively, we have data col­lec­tion sim­i­lar to the fol­low­ing with­out using any declared JavaScript variables:

s.pageName = "My Title"
s.products = ";Widget";

Let’s now take a look at the lis­ten­ing require­ment.  As I men­tioned, from the JavaScript file or tag con­tainer we can now query all the ele­ments that con­tain the class “ATM”, which is easy enough.  Some­thing like the fol­low­ing will col­lect our elements.

var elements = document.getElementsByClassName('ATM');
for(var i in elements) {
....
}

Within this loop we can then put the ele­ments with the id ‘title’ in s.pageName and the ele­ment with the id ‘prod­ucts’ in s.products.  This is not all that dif­fi­cult.  What can be dif­fi­cult is know­ing at what point all the data is there. After all, my page can do asyn­chro­nous requests for HTML and return within that string extra data about the page.  How do we account for this?

One option might be to use jQuery’s $(document).ready().  The jQuery library is a fairly well used library and even if you aren’t using it on your site, it is fairly easy to include within your tag con­tainer.  To use jQuery, we would wrap the code above in the $(document).ready() func­tion like this:

$(document).ready(function () {
var elements = document.getElementsByClassName('ATM');
for(var i in elements) {
....
}
});

If you do not want to include jQuery in your solu­tion you can approach this prob­lem dif­fer­ently.  One sug­ges­tion is to cre­ate an HTML ele­ment with the sole pur­pose of indi­cat­ing that the data is ready on the page.  Essen­tially, we would have a DOM ele­ment that resem­bles this:

<span class="ATM" id="ready"></span>

With this ele­ment you can asyn­chro­nously sur­face data in the DOM with­out con­cern for the order of exe­cu­tion.   The code for this might look some­thing like this:


s.wait = setInterval("s.isComplete()", 200);
s.isComplete = function() {
var n = 0;
if(document.getElementById('complete')) {
clearInterval(this.wait);
this.ready();
} else if(n++ == 5) {
clearInterval(this.wait);
}
};
s.ready=function(s,p){
var a = document.getElementsByClassName('ATM');
for(var i = 0; i<a.length;i++) {
var v = a[i].id;
if(v != 'complete')
s[v] = a[i].innerHTML;
}
};

Review: Does it Sat­isfy the Four Key Require­ments?
To review, we have data being set in HTML with tags and not JavaScript vari­ables.  We have at least one HTML ele­ment that is indi­cat­ing that the data is ready.  Finally we have JavaScript wait­ing for the HTML or data to be ready.  Let’s see if we’ve cre­ated some­thing that sat­is­fies our four basic requirements.

  1. Loosely Cou­pled Imple­men­ta­tion: We have cre­ated a way of sur­fac­ing data on the page that is loosely cou­pled.  We can add these ele­ments and with­out any form of data col­lec­tion there will be no errors.  If the HTML ele­ment serves no visual pur­pose we can make it hid­den and we are no worse for the wear.  HTML is just mark up.  It’s either ren­dered on the page, hid­den, or con­tains a ref­er­ence to another asset, but it doesn’t exe­cute, which means there is no poten­tial for JavaScript errors.
  2. Page Lis­tens For Data: With the JavaScript above, we are effec­tively lis­ten­ing for the page data.  When the com­plete ele­ment is loaded, the JavaScript will pull all the data ele­ments and send the request.
  3. No Order of Oper­a­tions Depen­den­cies: We’ve made the load order irrel­e­vant.  The JavaScript can be loaded at the top of the page or bot­tom – before the data ele­ments or after.  It really doesn’t matter.
  4. HTML Only – No JavaScript: We are cer­tainly only using HTML — no doubt about that.

The result is a very basic, but pow­er­ful solu­tion for using Tag­Man­ager to tag your pages using the data that is already on them. I would love your feed­back.  Is this a good idea or bad idea?  Does this make tag­ging eas­ier?  What do you think is miss­ing?  Feel free to add your com­ments below.

0 comments