Who are you, really?

This is primarily an analytics blog, but I’ve expanded my definition of “acceptable posts” a bit to include broader topics of interest to those in the industry. Part of being in any field is how we define ourselves in relation to it, and how attached we are (or aren’t) to our job. As humans, we tend to attach to temporary circumstances as if they were permanent, causing a lot of suffering when they are no longer around. We live in a rapidly changing industry, and our self-concept can suffer if we tie it to things that disappear.

How do you define yourself? Your job? The city you live in? Your home? Your marriage/relationship? Your dietary habits? Your family dynamic? Your possessions? Your pets? These are all impermanent. In fact, I’ve had total or partial losses or changes in every single one of these areas in 2020, and I’m still standing. That means that there is a part of me (and a part of you) that isn’t defined by any of these things, despite our insistence on introducing ourselves by these definitions. I didn’t disappear or fly away when all these things happened, which means who I am, and who you are, is larger than all of that.

The point of this post isn’t to dwell too long on my personally difficult year, but to illustrate that the things we think we depend on aren’t actually required for us to live a fulfilling life.

It’s easy to fall into alarmism these days – our whole field is seemingly at risk because of a browser change! Who’s down with ITP (yeah you know me?) Big companies are getting sued for privacy violations! CNAME records may be at risk! Webkit policies go brrrr! [Insert favorite extension here] is no longer available on the Chrome Web Store! Let’s take a deep breath and run some comparisons (and perhaps create a parody of “We Didn’t Start the Fire” while we’re at it).

Digital analytics as a field is constantly evolving. So many things that were “the death of analytics” have fallen flat, as have all previous predictions of the world at large ending. This is not to say that the industry is infallible by any stretch, or that it’s wrong to bring up potential big changes, but we can’t jump ahead to the worst conclusions before things are even productionalized. We also have to be realistic that entire industries transform unimaginably given sufficient time.

If, for example, analytics were forced to undergo a transformation as vast as the one from horse-drawn carriages to cars (or, more aptly, from slide rules to calculators), would this really be a bad thing? Innovation for innovation’s sake isn’t what I’m after, but innovation that moves the world forward and gets people to their intended result more quickly is a net positive. The first stage of innovation is upheaval and disruption of established norms. At this stage, everything looks crazy from the outside and the new method/product hasn’t achieved wide acceptance yet. As time passes and acceptance grows, some of the initially reticent people will come to accept it, followed by eventually the most skeptical. It’s all part of the product adoption curve, which can be applied to technologies/approaches in addition to actual products.

Most of the well-known writers in this industry are innovators/early adopters in terms of this curve. That means that they’re learning about things as they occur, and those things may or may not take off enough to reach full adoption. That’s part of why we can’t be overly alarmist each time something new comes down the line. It’s a tight balance between staying informed and information overload/analysis paralysis.

To succeed and grow, we must find a home within ourselves as people independent of outside forces. From our solid foundation, we can bring our whole selves to our jobs, ready to weather the forces of change, and know ourselves as larger than our circumstances. We are nothing if not our ability to adapt and prosper from seeming adversity.

When I think about these concepts, I can’t help but hear the voice of Tyler Durden: “You are not your job. You are not the contents of your wallet.” Of course, he goes on to say “You are the all-singing, all-dancing crap of the world,” which is the opposite of what I’m saying to you.

Granted, everyone can feel like that at times, but what I’m trying to eventually get to is a message of…hope? I’m not all the way there, but may we all achieve a strong enough sense of ourselves that we can know who we are outside of the constantly changing background of circumstances. Who might that be? Someone who knows themselves, their intentions, what they value, and how well they can adapt in any situation.

Games of Chance, Analytics, and Life

I’ve come to notice over the past few years an interesting overlap between those interested in analytics and those interested in gambling. I’ll be the first to admit that I have a long-held aversion to gambling, and at one point actually took vows that prohibited it as part of a mindfulness practice. (They’ve since expired, but I still haven’t participated.) However, I’ve been conducting an inquiry into why this overlap exists, which has led me down an interesting psychological and intellectual pathway worth detailing.

The common theme among many analytics professionals whose work I respect has been an interest in poker, a game of chance, skill, psychological profiling of self and others, good old fashioned razzing your opponents, and calculated risk, among other things. As I thought more about this, I began to see where this dovetailed with both key focuses of an analytics career, as well as an approach to life in general.

Part I: Chance, Skill, and Calculated Risk

Many of us have come from or at some point worked in the world of startups, whether that be marketing technology companies, early employees of the major vendors, smaller agencies, or otherwise. To succeed in this world requires a level of risk-taking and openness to experience that not everyone possesses, with no guarantees of success. Those startups that bend the odds in their favor do so because of factors such as timing of their product launch, the state of the market/competition, resonance with users, the image the company projects, and, sometimes, the personal charisma of the founders and/or spokespeople. Additionally, stock options, often offered to early employees, are themselves a gamble. So much of this is “right place, right time” type of luck, but a percentage of it is skill. VC firms invest in a portfolio of companies, expecting many of them to fail, but making up for it with a few outsized successes.

To succeed in poker requires a similar combination of factors. There are mathematical odds that can be calculated at every step, but there is a human factor that can bend the game in a particular direction. Players that succeed do so because of factors such as the relative inexperience or exploitable qualities of others at the table (state of the market/competition), ability to stay multiple steps ahead and project what others might do (which translates to building an effective user experience, as well as an effective company), and an ability to control how others see them (image/charisma). Ultimately, however, the game is played against the unforgiving master of probability combined with human psychology, which can create winner’s tilt (startups that are unicorns due to some chance factor who then go on to risk everything and lose it all), or bad tilt (startups that have a hard time acquiring customers, acquire a bad attitude instead, and end with the founders throwing in the towel and/or selling the company in a fire sale).

(For those unfamiliar with these terms, you can read further about understanding tilt and avoiding tilt.)

It’s easy to see why someone willing to gamble on a startup (or willing to enter a field that is fairly new and constantly changing) would be willing, able, and interested in literal gambling.

Part II: Psychological Profiling

To succeed in the corporate world requires self-knowledge, as well as an understanding of how to interact with varying personalities and groups. This is actively encouraged, particularly as one approaches the executive levels. The vast array of coaching, personality inventories, and team building boggles the mind (and accounts for a very large industry). There is nothing wrong with this, as there’s value for business and for life in having a realistic assessment of one’s own strengths and weaknesses, as well as how those interplay with those of others. However, this can quickly veer into unproven methodologies, the poppiest of pop psychology, etc.

Skill in poker also involves quite a bit of psychological profiling. As players advance, they are encouraged to assess the others at the table in terms of where they’re from, their tells, their appearance, their demeanor, etc. This can translate into an intuition for how they might behave or perceive the actions someone else takes, which can be exploited for gain. The gain in poker is taking someone else’s [real or theoretical] money, whereas the gain in business is getting others to work well with you. It can also, however, translate to stealing customers from a competitor when a crack is discovered in the façade of their product, which brings us to our next point.

Part III: Razzing Your Opponents

Many companies, particularly smaller ones but some larger ones as well, create a bond among their employees over outfoxing the competition. Any misstep by a competitor is celebrated and viewed as an opportunity to make fun of them (usually off the record), pursue that company’s frustrated clients with the promise of a better experience, or simply enjoy the schadenfreude. Sometimes this translates to the public space, such as John Legere’s direct tweets lovingly insulting other cellular providers in recent years.

Realistically, though, it’s also important not to underestimate the competition, or assume they’re not doing their due diligence on you as well. As humans, we tend to overestimate the amount of success due to our own skill and underestimate the role of luck. This relates to hindsight bias and hyperactive pattern detection. (Very interesting reading the The Atlantic on this phenomenon in general, and in The Sydney Morning Herald as it applies to poker and the stock market.)

In poker, putting others on tilt by finding their buttons is encouraged. Knowing them better than they know themselves and not letting them get comfortable are real strategies. Here we find something likely to be familiar to our aforementioned early startup employees: projecting a larger-than-life image and needling the competition. Brings to mind Salesforce’s early days of staging fake protests and commandeering taxis at competitors’ events.

Part IV: An Approach to Life

So, where does that leave us? What if one isn’t interested in putting real or imaginary money on the line, but finds these concepts fascinating? You might be someone who gambles with their life, which is actually all of us. I don’t mean in the sense of risking death per se, but we all take calculated risks every day (which goes without saying during COVID-19 especially).

To assess our risks and life choices requires the following:

  1. An understanding of cognitive biases
  2. Mindfulness of our thoughts
  3. Realistic odds calculation (e.g. understanding of real-life probability)
  4. A decision to act

These are solid life skills I don’t hesitate to universally recommend. If poker gets you there, great. My cautions are 3:

  1. The obvious risks of financial ruin and addictive behavior. If you’re struggling with these, there are resources like this one, which includes a great chart further down on how to satisfy the same urges that cause problem gambling, as well as organizations on the topic.
  2. The risks to one’s worldview. What do I mean by this? I’ll use the example of when I did a fair bit of karate at one point in my life. This caused me to view every public encounter from the perspective of which escape routes I had and which moves I could pull if someone came at me from various angles. When you have a hammer, everything’s a nail. Similarly, if you view life from a poker perspective, it’s a zero sum game, where intentions conflict and players don’t cooperate around a common goal. “But isn’t life actually like that, Anne?” Not necessarily, though game theory is interesting and includes more than this approach. I find Stephen Covey’s book The Third Alternative an interesting perspective as well if you want to get away from zero-sum thinking (concept here, book here).
  3. The motivation that gets you to the game. If it fulfills a need for you and doesn’t cause problems in your life, all the better. It’s important to be realistic about what brings you to the table. I’ve seen a pattern where people sign up to break themselves against the odds at times when the rest of their life has gotten out of control. Games can provide a controlled microcosm in which to play out our psychological tendencies, and can be an expression of avoidance or desperation. They can also be a fun diversion.

Overall, my inquiry has led me to a deeper appreciation of the parallels, life skills, and complexity behind the game. I don’t know if I’ll ever play personally or not, but I’ve learned a lot toying with these ideas. If you have experience with these areas, feel free to share in the comments.

Additional articles of interest:

How I Used Professional Poker to Become a Data Scientist

Psychology and Poker

Hold or Fold – Playing Your Big Data Hand to Win

What UTM Tags and Poker Have in Common (funny video)

Tracking YouTube Videos in iFrames with Adobe Launch: A Simpler Approach

Making this process a little less painful by going as directly as possible to the YouTube API.


Embedded YouTube videos in iFrames are everyone’s favorite (read: least favorite) scenario to encounter when designing tracking for a site, particularly if you do not have access to development resources to send details on video activity. Fortunately, there are ways for you to manage this entirely yourself!

What Doesn’t Work

First, let’s rule out some things that won’t work in this scenario so you know what to avoid:

The Built-in Core Extension’s Media – Play, Pause, etc. Events: Using the CSS selector of the iFrame or the surrounding components will not properly pick up the events in this scenario.

The Adobe Analytics for Video Launch Extension: This still requires you to take an additional step of mapping the events received from YouTube, which we’ll do here with some simple code without having to use this extension.

The YouTube Embed Extension for Adobe Launch: If your video already exists on the page, this won’t help you, as this extension is used to insert videos on the page.

Past Solutions from DTM

Next, let’s discuss some past solutions from the world of DTM:

Adobe’s DTM Recommendation: This requires additional parameters to be added onto the video URL (which we can do from our side in the tag manager, rather than rely on making updates across the whole site). It also requires the additional of a large custom code block for the Adobe Media Tracking code.

33Sticks DTM Recommendation: This is a great place to start, as it automatically appends the proper parameters onto the video with no work from other developers. However, perhaps you’re trying to reduce the amount of custom code you have overall, and you may not want to rely on the continued functioning of the raw Adobe Analytics Media Module code in the world of Launch.

Can we do the same thing with fewer lines of code and without relying on things like Heartbeat, the Media Module, etc.? Turns out we can!

How This All Got Started

I was working through a particularly ornery YouTube video tracking scenario and wanted to start completely from scratch to get the cleanest possible solution with the least amount of code that I felt would maintain well long-term. The YouTube API seems fairly stable, and as long as that doesn’t change significantly (and if it did, it would be clearly announced), this code should continue to work for a good while.

I was playing around with multiple options, and had a jam session with the fantastic Jim Gordon, owner of what I’ll call my “brother site”, Jimalytics and creator of the Tagtician Chrome extension. We both played around in the console for awhile, I hit upon the different event states, and we had an impromptu hackathon where this all came together pretty quickly. The majority of the second code block is based his work while we talked through it in that session. I’ve made additional modifications for my use case and written up the details so we can share this with the world.

Requirements for this Solution

We’ll need the following items for this work:

  • The addition of the enablejsapi parameter to the video URL and a unique player ID to be appended to each video on the page (even if you have only one video on the page, it still needs an ID). This allows the items from within the iFrame to communicate with the surrounding site.
  • Code to listen for the YouTube events and map them to _satellite.track call
  • Rules set up in Adobe Launch to listen for the direct calls you set up above
  • Events and Variables configured in Adobe Analytics admin to receive these events

Assumptions: you are running an existing, functional implementation of Adobe Analytics and Experience Cloud ID service on your site.

Part 1: Adding the enablejsapi parameter and unique player IDs to all YouTube videos on the site

Jason Thompson has already done exactly this in the first part of the above 33Sticks post, so we can use the same method – no need to change what works!

We’ll use this to append the parameters and IDs in cases where we see that the Enable JS API parameter is not already present.

This code should go in the Adobe Analytics extension in the “Configure Tracker Using Custom Code” section. (General note: when copying/pasting code, ensure proper formatting is retained, and ideally paste into a plaintext file or code editor to save locally before adding to Adobe Launch.)

/*Video Code Block 1 of 2: Append Enable JS API Parameter and Unique Video ID for Video Tracking.*/
var n=0;

jQuery('iframe').each(function() {
 var src = jQuery(this).attr('src');
	if (src.indexOf('youtube.com') > -1) {
    	if (src.indexOf('?') > -1) {
			if (src.indexOf('enablejsapi') == -1) {
				src = src + '&enablejsapi=1';
     	} else {
	 		src = src + '?enablejsapi=1';

		jQuery(this).attr('id','player' +n);


Part 2: Code to Listen for the YouTube events and map them to _satellite.track calls

Here’s, it’s important to understand the values that the YouTube API passes back for the various video states:

  • -1 – unstarted
  • 0 – ended
  • 1 – playing
  • 2 – paused
  • 3 – buffering
  • 5 – video cued

We’ll reference these numbers in the code, so this will help you understand what is happening in the case statements you see. You can read the full YouTube API documentation here, but you don’t need most of it for this solution; feel free to reference if you want to customize further. You might also see the following in other code:

  • YT.PlayerState.ENDED
  • YT.PlayerState.PLAYING
  • YT.PlayerState.PAUSED
  • YT.PlayerState.BUFFERING
  • YT.PlayerState.CUED

These are identical to the above numeric values, and we’ll be using the numeric values only in this example.

Key things to know:

  • This example tracks 3 events: start, end, and pause. This code can be modified using the event codes listed above to add additional case statements as needed.
  • This code doesn’t collect video name but could easily be modified to do so using after reading through the YouTube API details, or you could grab the document.title from the overall window in a data element for later use, whatever makes the most sense for your use case.
  • This code example assumes there is always only 1 video per page, and that you are using the script above to insert the player names. That is why the name “player0” is hard-coded in. You can make this piece of the code dynamic to look for any player name according to the syntax you are using.
  • Auto-play videos sometimes play too soon to be caught immediately if the Adobe code takes time to load.
  • The channel name can be a name that you specify. In 2 locations, I have the placeholder text “channelnameofyourchoice.” Change this to a more meaningful name describing the type of videos your site hosts.

Without further ado, here is the second block to add just beneath the earlier one in the “Configure Tracker Using Custom Code” section of the Adobe Analytics extension.

/*Video Code Block 2 of 2: Add event listener and fire _satellite.track rules. */ 

try {var addYoutubeEventListener = (function() {

    var callbacks = [];
    var iframeId = 0;

    return function (iframe, callback) {

        // init message listener that will receive messages from youtube iframes

        if(iframeId === 0) {
            window.addEventListener("message", function (e) {

                if(e.origin !== "https://www.youtube.com" || e.data === undefined) return;
                try {
                    var data = JSON.parse(e.data);
                    if(data.event !== 'onStateChange') return;

                    var callback = callbacks[data.id];
                catch(e) {}

        // store callback
        callbacks[iframeId] = callback;
        var currentFrameId = iframeId;

        // sendMessage to frame to start receiving messages
        iframe.addEventListener("load", function () {
            var message = JSON.stringify({
                event: 'listening',
                id: currentFrameId,
                channel: 'channelnameofyourchoice'

            iframe.contentWindow.postMessage(message, 'https://www.youtube.com');

            message = JSON.stringify({
                event: "command",
                func: "addEventListener",
                args: ["onStateChange"],
                id: currentFrameId,
                channel: "channelnameofyourchoice"
            iframe.contentWindow.postMessage(message, 'https://www.youtube.com');

addYoutubeEventListener(document.getElementById("player0"), function(e) {
    switch(e.info) {
        case 1:
        case 0:
        case 2:

catch(err) {console.log("Video Tracking Not Present");}

Part 3: Set up Rules in Adobe Launch to Capture The Direct Calls

Now that you have added the appropriate parameters to the video and captured the events from the video, you want to ensure these events make it into Adobe Analytics. For purposes of this post, we’re going to assume you have the ability to create new rules in your Adobe Launch environment, and that you’re an experienced Adobe Analytics administrator who has already set up the appropriate events for the different video states you’d like to track.

In my example above, I am sending video_start, video_end, and video_pause. I’ll need to create one rule for each.

Name each new Launch rule according to your rule naming convention. (What? you don’t have one? Jim and I agree on that as well – check out his post here. I tend to use a modification of this in a lot of my implementations using the same principles. He’s written them up in a concise way in this article.)

In the “IF” section, select “Core” as the Extension and “Direct Call” as the event type. In the “identifier” section, enter the same text you are sending in the _satellite.track calls in your code, for example video_start for the Video Start rule. Keep your changes and go back to the main rule.

In the Conditions section, you have the option to save yourself a lot of server calls (i.e. money). Do you really want to fire something every single time every visitor plays, pauses, or ends a video, especially if there are a lot of visitors and/or a lot of videos and/or really distracted visitors who pause a lot? If you only want to know whether something occurred at least once, you can set a condition using logic type Regular, the “Core” extension, and a “Max Frequency” condition type. You can set it to return true no more than once every “1” page views. This will prevent the call from going out over and over again if people are taking multiple actions. You’ll be able to see the difference if you look at your network calls before and after implementing the max frequency setting.

In the Actions section, you’ll want Adobe Analytics – Clear Variables, Adobe Analytics – Set Variables, and Adobe Analytics – Send Beacon.

  • In the Set Variables item, select the appropriate event to fire, and add any additional informational eVars you might want to configure for the video name, etc.
  • In the Send Beacon section, select the s.tl() option so that the event is not treated as a new page view. You can optionally enter a custom link name to describe the video action, but this is not required and is a bit duplicative.

Testing On Your Site

Build your changes into a development library. Navigate to a page where a video is present on your site, either on a page on your lower environment, or by going to your production site and using something like the Launch and DTM Switch Chrome extension (or the Charles Proxy Map Remote function if you’re feeling fancy or not using Chrome) to switch out the environment reference to use your development library on the prod site. Take various actions on the video while monitoring your network calls or looking in a debugger and ensure the events fire when you expect them to. If everything looks good, publish and re-test on production.

Final Thoughts

Our little experiment turned into something that can hopefully be of use to a larger audience. Play around and see what works for you!


What they don’t teach you in DTM school

This article assumes a solid general tag manager as well as DTM-specific knowledge base. It will help take you from a “by the book” example implementation to the much messier real world.

There are also some bonus non-DTM tips in here as well.

1. You cannot set events using both s.events in custom code and in the UI*

Let’s say you are setting s.events in custom code because you need to set events equal to currency amounts rather than just increment them, since this is a limitation of the UI.

You might have something like (example order confirmation scenario):

s.events= “event59=”+_satellite.getVar(‘orderTotalProductDiscount’)+”,event60=”+_satellite.getVar(‘orderLevelProductRevenue’)+”,purchase”;

Then, you might later come into the UI and add an event in the Events area. This would be a mistake. The custom code will override the UI, and the UI entry will be meaningless. You have to now add ALL events on the given rule in the custom code section.

*Update: you can, but it’s not the best nor intuitive. See Jenn Kunz’s comment on this post for more.

2. You must avoid special characters in product syntax merchandising eVars to avoid conflict with the product string

Merchandising eVars should not use any characters that are reserved due to their functions in the product string. Prime examples include the semicolon (used to separate pieces of the product string), the pipe | which is used to separate merchandising eVars from each other, or a comma, which is used to end an iteration of the product string. This may seem like common sense, but these sorts of characters are remarkably common in data layers, particularly those serving dual purpose for Google Analytics. Characters like the pipe are used to separate page hierarchies, for example ( Level 1 | Level 2 | Level 3 ). I try to avoid the following characters to stay out of trouble:

*Avoid the below completely or replace with a space

& ; , + % @ # ! * () {} [] ‘ ” =

*Replace | with /

*Avoid hidden or non-ASCII characters

3. “Data element changed” has several limitations

To detect a change in a data element, DTM listens periodically for changes. This makes it attractive as a rule condition. However, “periodically” is often not enough when the change occurs when moving from one page to another. Alternatives that pick up more quickly are using _satellite.track and setting up a direct call rule, or using a CSS selector in an event-based rule if it applies if you are fairly confident it is stable and will not change (keep tabs on it anyway). All of these will be detected more quickly than data element changed.

The second limitation is that data element changed is text-based, not time-based. What I mean is that it is looking for a change in the contents of the data element, but if you push the same text to the data element again, it won’t be detected as a change. Let’s say that you do 2 of the same thing in a row, for example adding an item to the cart from a given page. If you have a data element showing the contents of your event array, and you are depending on it to change to trigger add to cart-related items, it will only trigger once for the 2 add to carts you did from the page if your data element just picks up “addToCart” each time (or whatever text is in the data element.) A way around this is to send an incrementing number at the end of the text string (e.g addToCart1, addToCart2) so it gets detected as a change. This is somewhat inelegant but gets the job done. I have had to use it when I had a structure I couldn’t modify and insufficient dev hours to make an ideal set of changes, for example.

4. There are more special characters to avoid in classification uploads than those listed in Adobe’s help documentation

OK, this one is not DTM-specific, but it’s still a “what they don’t tell you.”

*You cannot use single quotes around data in a classification file. You might be tempted to do this to avoid leading 0’s from being removed from a product ID, for example. However, if you do, it will cause issues with your upload and has been confirmed by my own frustration and client care’s subsequent confirmation that this should be avoided. This is not documented anywhere that I have seen that single quotes surrounding cell data cause issues, but they definitely do. The solution is to use something other than Excel (basic text editors, etc.) to edit the file so the leading 0’s do not get cut off or change your Excel settings accordingly.

*This may be obvious but it happens all the time – avoid using the separator character in the file if at all possible (e.g. tabs within a cell within a tab-separated file). If you must: you can get around this by changing v:2.0 to v:2.1 in cell C1 in the classification template. You can also escape the special characters.

*Using tab (/t), form feed (/r), new line (/n), double quote (“), caret (^), or pound (#) are all no-nos within a cell unless you escape them. The pound symbol within a cell will get your data interpreted as a comment and ignored, which you don’t want, for example.

*Something that doesn’t get repeated often enough: the first row under the header must be blank in the file; your data starts on the following row. If you don’t do this, your file won’t always upload.

5. There are non-publicly documented differences in default allocation for the pages (s.pagename) report between different Adobe products

(Another non-DTM item, but very important to understand.)

Reports and Analytics: uses linear allocation

Workspace: only shows values set on the same hit where the pageName is set

Data Warehouse: uses linear allocation

Ad Hoc Analysis: can be set to default, last, or linear allocation

This means your data will very likely not match if you are looking at the Pages report for a given set of events in R&A vs. Workspace.

6. When you set up the Google Analytics tool in DTM, don’t choose “Google Analytics”

Because you might want to go back in time to before October 2012, it’s still possible to use ga.js rather than analytics.js. You really don’t want to, though. If you want a recognizable, modern GA with enhanced eCommerce capabilities, you will want to add the “Google Universal Analytics” tool. If you choose “Google Analytics” by mistake, enjoy your trip back to the early days of web analytics. Perhaps we can also add an option for Urchin, or Site Counter. I digress.

7. Common marketing tags that you would copy/paste as custom JavaScript or HTML in other tools must be rewritten if you want to run them as non-sequential JavaScript

There are many things that need to happen above and beyond removing surrounding script tags for JS-based marketing tags to run successfully as non-sequential JavaScript in DTM. You will have to rewrite many common tags. Jenn Kunz has a great article on specifics with some good examples here.The recent, uh, “launch” of Adobe Launch (the newest Adobe tag manager) offers hope for this scenario and many others mentioned above, and as it continues to evolve I hope to see these scenarios and more handled.

Testing Checkout Without Using Your Own Credit Card

Don’t use your personal credit card when test credit cards abound!

Proper revenue recording is a critical piece of analytics implementation and testing, but I’m always surprised how few vendors and analysts seem to be aware of the publicly available test credit numbers that are available for use. I’ve heard too many instances of people using their own (real!) cards and then cancelling the purchase, or even actually buying things from the site for test purposes. That’s fine if you actually want to make a purchase, but given the amount of test scenarios required, that can become an expensive habit quickly.

Payment processors typically accept a standard suite of test credit cards that will allow an order to go through on the site, but that are flagged after the fact as a test card and the order is not fulfilled. If you are doing this on production versions of the site, be forewarned that this can impact your order-related metrics both in the analytics platform (artificially increase them provided your IP isn’t blocked in the platform you are validating in) and increase error rates in order management systems since this (as intended) won’t actually go through. It is also true that certain sites are configured to not accept test credit cards in their production instance, so you may receive an error; however, the majority of sites will allow these to be used.

With those caveats out of the way, allow me to introduce you to the standard suite of test cards:


This is one of the best resources out there and includes many different scenarios and international cards as well.

The testing procedure is as follows:

  • Go through the normal process to add items to your cart and proceed to checkout
  • For the name, it is helpful to use “Test Test” or something similar so it’s clear this isn’t a real order
  • For email address, it’s ideal to use a valid one you have access to, so that you can receive the order confirmation email
  • For shipping/billing address and phone, use clearly phony data that still meets validation criteria (e.g. 123 Main Street in a given city and 212-555-5555 as the phone)
  • For the CVV (3-4 digit code), use any set of numbers
  • For the expiration date, use any future month/year combination

The site will inform you if there is any error confirming the order, but most times, you’ll get through. Make sure to have your debugger and/or console open and recording prior to purchase so you can see the analytics call come through. I’ll be sending this post as a reference next time I hear talk of someone using a personal card for analytics testing!

The Data Layer: A Primer

The data layer is a key part of most modern web analytics implementations, but it seems there are not many resources to explain it to a less technical audience, or perhaps to someone who is technical but new to working with it. Let’s start with the basics:

What is it? In the world of the W3C data layer (more on that in a minute), the data layer is a JSON object.

To break that statement down, W3C is the World Wide Web Consortium. They provide standards for the web that align architecture and design principles so that the web can work well and continue to grow. (This may seem unnecessary because it seems like the internet “just works”, but if you weren’t around for the wild west days where there were vast differences between what different browsers supported across the web, standards are most welcome and necessary.)

JSON is JavaScript Object Notation. JSON is a way to organize and structure data objects in a human-readable way. It answers the questions “What is this item called, and what is its value?” For example, to take a somewhat amusing example from the W3C’s full documentation, how easy would it be (without knowing anything about the data layer) to answer the question of which product we are viewing here?

digitalData.product[n].productInfo = {
productID: “rog3000”,
productName: “Rogaine”,
description: “Hair Regrowth”,
productURL: “http://site.com/r.html”,
productImage: “http://site.com/rog300_large.png”, productThumbnail: “http://site.com/rog300_thumb.png”, manufacturer: “Pharma”,size: “300ml” };

Pretty simple to see, right? It’s easy to look at this and see the items and what they represent. Contrast this with something like s.eVar47= “rog3000” (which is how the productID piece of this would look if it was hard-coded and assigned to Adobe Analytics conversion variable 47), and you can see how much more human readable this format is.

Why is it? There are many advantages of the data layer, but here are a few. The data layer allows for a simple place to funnel all the data about your website into an organized format that can later be referenced by analytics tools, marketing tags, and more. This helps ensure that you are passing the same data across tools, and gives the flexibility to assign the product name to, say, variable 37 today but variable 40 tomorrow. (Not that I recommend bouncing around which variable you are using without a very good reason, but that’s one example.)

In the past, with hard-coded implementations, you would need to do things such as specify that it was a particular variable number associated with the product name value, and your development team would have to make that adjustment if things ever changed. Using a data layer also allows you to more easily send data to multiple analytics tools (for example if you have both an Adobe Analytics and a Google Analytics implementation running, they can both reference the same set of objects on the site).

As websites evolve, tasks like updating a manual variable assignment get more cumbersome and error-prone, and introducing inconsistencies generally ends badly in terms of data quality. The data layer takes all that out and provides an easy (and again, human-readable) reference point.

Using the data layer with a tag management system (things like Google Tag Manager, Adobe’s Dynamic Tag Manager [DTM], Tealium, Signal, Ensighten, etc.) allows the analytics team to make adjustments like this without waiting on a formal release or involving a development team. It also allows the development team to keep the analytics data flow consistent during major redesigns of the site. It’s easier to see the requirements and they are more meaningful, versus less human readable lines of code that have to continue to be explained and defined. There’s plenty of defining that goes on when creating a data layer as well, but the starting point is much more understandable.

How are objects referred to within the data layer? The path to an object is referenced with dot notation. In the below example digitalData object, to refer to the pageType, I would refer to digitalData.page.category.pageType. This is the type of notation that a tag manager would use.

digitalData.page.category = {

primaryCategory: “FAQ Pages”,

subCategory1: “ProductInfo”,

pageType: “FAQ”};

Is it always called “digitalData”? There are many names for the data layer. The W3C standard name is digitalData, but tag managers like Tealium use utag_data, you will see dataLayer with Google Tag Manager, etc., plus you may see companies that use their own custom names.

Where can I see the data layer? You can open your browser’s console and enter the name of the data layer (see above for common ones), and you will get back a list of key/value pairs within a structure. Some of the data layer may also be visible in the page source depending on many factors, but the console is the most direct and accurate way to see the current values.

To get back the value of only a specific item, you can enter the dot notation format. In the example a few paragraphs up, if I were to enter digitalData.page.category.pageType in the console, I would get back “FAQ”.

How does it fit into the analytics ecosystem? Here is a very basic example of the way the data layer can power an analytics implementation (taking into account the fact that I am not a graphic designer by any stretch of the imagination):

digital data layer process flow

Where do I go from here? Learn more about the specific analytics solutions you are working with and explore how the data layer is set up on your site. This training will vary significantly by tool.

I did not go into JSON arrays since this is a basic intro, but they are very important since they are often used for the products that are being viewed (as one example), and that is very important for most web analytics solutions. It would be good to go through the whole JSON section from W3Schools.

Hope you are able to take some newfound understanding of the process flow and use it to further your web analytics journey!

Update: if you’ve read this and are still asking the question, “Why can’t I just use CSS selectors for everything?”, please read this colorful response from Jim Gordon’s blog: https://jimalytics.com/implementation/data-layer-or-css-selectors/

“It’s just widgets!”: The Dangers of Oversimplification

You could be a web analytics hero with 100 implementations under your belt, a winner of Kaggle competitions, a creator of your own AI platform, and still be perceived as incompetent because of communication and wording issues.

A few years ago, I was presenting at an event and was speaking with people from many different companies beforehand. I was briefly going into the particulars of the business I was in at that time, and the person I was speaking with cut me off and said, “Yeah, it’s all just widgets. No matter what the industry, everyone is just trying to sell more widgets.” Well…not entirely.

The goal of most for-profit companies is to improve their revenue over time, granted. There might be a number of variations on that theme such as increasing market share, changing the product mix in a desired way, launching in a new geographic area, etc.

There are absolutely also non-profit entities whose true goal may lie within the “awareness” space, simply getting people to perform actions in keeping with public or personal health or read about a condition without a specific financial or donation goal in mind (and, of course, plenty that do have a donation goal in mind required to sustain the organization.)

However, the important thing here (and by “here,” I mean from a web analytics perspective) is that an understanding of general business structure and practices does not equate to a specific group or client’s confidence in your abilities.

The reason you are likely working on a web analytics project is that you have the expertise to do so, or are in the process of getting it, and the group or individual that asked you to does not have that time or expertise. The person you are doing it for is (generally) unlikely to evaluate you on your technical skill during a project unless something majorly breaks. So what do they base their perception on?

Often, it’s how accurately you translate their requirements back to them in language that makes sense, and your demeanor in doing so.

Let’s come back to the widgets. If I am in the healthcare field and have hired you to do an implementation for a patient portal, and I refer to the people on this site as “patients”, how will I feel if you say, “OK, you want more sign-up thingies, got it”? The language may not be quite as crude, but you can begin to form an idea of how this might come across. It’s important that the analytics professional reflect back the requirements in the language that the business is actually using, for reasons of precision and mutual understanding. A happy consequence is that the group or client feels heard (reflective listening skills) and is more confident in your abilities (because you appear to listen and properly use terms that they know about.)

Worth highlighting again: this all happens regardless of your actual skill level in analytics. You could be a web analytics hero with 100 implementations under your belt, a winner of Kaggle competitions, a creator of your own AI platform, and still be perceived as incompetent because of communication and wording issues. Perception is not based on your actual skill level since there is often no benchmark to compare you to in the world of the people you are assisting.

So: if you’re great at technical analytics or reporting, the way to get people to realize it is through picking up on proper wording and tone for who you’re working with. If you’re still learning a lot about analytics and reporting, the way to gain trust to take on larger projects is to create satisfaction on the ones you’re working on now through good communication skills. There is no downside!



The Analytics Bookmark List I Wish I’d Had When I Started

Save time and hold onto these!

This list is a distillation of helpful resources for bookmarking/saving. You can use this post as part of a new hire onboarding plan, or for yourself to keep organized and up to date on analytics happenings.

Analytics Platform Login Pages

Adobe Analytics Enterprise Login

Adobe Analytics Marketing Cloud Login

Google Analytics Login

Tag Manager Login Pages

Adobe Dynamic Tag Manager (DTM) Login

Google Tag Manager (GTM) Login

Tealium Login

Ensighten Login

Debugging Tools

Adobe Analytics Debugger: Useful for validating basic pageload-level props, eVars, events, products, and simple attributes such as “JavaScript enabled” status. Not as useful for reviewing pages with multiple calls, post-pageload activity, custom links, etc. (Bookmarklet – create a placeholder bookmark and enter the JavaScript code provided at this link as the “URL” of the bookmark and place on your bookmarks bar, then click once you are on a site with an implementation.)

Disruptive Debugger: Useful for validating Adobe DTM data element values and whether or not rules load; will pick up post-pageload activity. Data element values change as they come in – will not record previous value but will just update to most current value. (This is a bookmarklet as well – see definition above.)

GTM Debugging Tools: article references multiple helpful tools, some GTM-specific, others more broad.

dataslayer Debugger: cross-platform debugger compatible with DTM, GTM, Tealium, and TagCommander; can monitor any W3C data layer.

WASP (Web Analytics Solution Profiler): WASP inspector is a Google Chrome extension that runs through the Chrome developer tools area. It detects tags across all platforms and offers more insight into the GTM data layer. (WASP profiler is their paid product, but the inspector is free.)

Charles Proxy: useful for debugging complex raw analytics calls and monitoring a continuous stream of activity with recording; can be used with mobile apps for live debugging. Requires a license after a 30 day free trial. Requires some time up front to properly set up certificates if using with a mobile device.

Analytics Blogs and News


Justin Cutroni (GA, thought leadership)

Avinash Kaushik (GA, thought leadership)

Simo Ahava (GTM)

Daniel Carlbom (GTM, GA)

Web Analytics Demystified (cross-platform strategy)

Jenn Kunz (Adobe DTM and data layer strategy)

Adobe blog posts related to analytics

Release Notes

Adobe Analytics/Experience Cloud Release Notes

Google Analytics Release Notes

Industry News (broader landscape)

Search Engine Watch (major marketing channels and analytics)

CMO.com (by Adobe)

eMarketer (research/benchmarking)

Econsultancy (market research)

Information Week (IT/big data)

CIO (business systems and trends)

Professional Associations

Digital Analytics Assocation


Virtues of Web Analytics: Persistence

Most quality solutions require first going through an amount of frustration that would cause many people to simply give up. Keep persisting, and by doing so, you’ll open the door to greater adventures.

For the intro to the Virtues of Web Analytics series, see the first post.

There are 2 parts of analytics that immediately come to mind when I think of persistence: getting the right people to care about the trends and tools that are important to you, and getting to the bottom of technical or analytical problems.

Neither one is for the faint of heart.

Part I: Getting the right people to care about the trends and tools that are important to you

Many people outside analytics view the entire field as a numbers game and analysts as sort of glorified bean-counters. Another view is that analytics teams speak in a sort of techno-babble that is not worth taking the time to understand, and doesn’t pertain to what other teams are doing. Others have no concept of the field or know just enough to be dangerous. A select few have previously done this work or are very knowledgeable about it. Our task here is to make connections with the rest of the business, regardless of their level of knowledge, in order to overcome misconceptions. One of the easiest ways to do this is to come to the table with a solution or an opportunity you’ve noticed that will directly benefit the group you are speaking with.

To arrive at what might help you connect with a group, you first have to know what is important to them. You might first have a meeting (or devote the initial part of a meeting) to understanding the goals and challenges of the group you’re connecting with, and devote the second meeting/part of the meeting to how your skills and tools can help give the group insight on the needs they express. However, this is not a “one and done” type of relationship. It’s important to keep up to date on how the group evolves their goals, and how they are using (or not using) what you bring to the table. A monthly or quarterly check-in is not a bad idea if you are trying to establish an ongoing relationship, even within a single company. This is an especially good idea if you are proposing sharing the cost of a tool that will benefit another group in addition to your own, or you are trying to get a group to adopt your analytical recommendations.

If you do have a proposal that involves someone else spending money on analytics tools within your company, build trust several months ahead of that; having that as your first ask sours the relationship and doesn’t allow you to prove the value of what you do outside of that context. (In the event that you’re questioning the value of what you do: If you don’t trust your own skills or the quality of the analytics practice where you work, what can you do to change that? There are both free and paid courses, professional associations, conferences, books, articles, podcasts, and more all over at your disposal. That’s a whole ‘nother post.)

Part 2: Getting to the bottom of technical or analytical problems

The first section deals mainly with persistence in your interactions with others. This section is all about you. Any mildly experience analytics pro deals regularly with difficult technical or analysis requests outside the neatly packaged world of ideal KPIs. This is the proving ground on which you can differentiate yourself, through both your actual solution and the way you act while you work through it.

Most quality solutions require first going through an amount of frustration that would cause many people to simply give up. Knowing at the beginning of the game that you will get to this point is helpful. Step back, breathe, take a walk, do something, but don’t let yourself get caught in a cycle of frustration and anger at yourself or the situation. There are many opportunities to practice mindfulness in this field. (Potentially also a whole ‘nother post.) Keep going through this cycle, which often feels like throwing yourself at a wall, over and over, until you start to happen upon something that works (and learn to laugh at yourself.)

Learning many of the major analytics tools in the first place requires a certain amount of “grit” and pushing through feeling less than intelligent at times. If you haven’t started on that journey yet, keep that in mind – don’t let it prevent you from starting, just remember it when you experience frustration, knowing that we all have.

You’ll notice that none of these ideas are quick fixes. Keep persisting, and by doing so, you’ll open the door to greater adventures.

Virtues of Web Analytics: Humility

Since we all can’t be up to date on everything all the time, there is huge benefit in listening to alternative perspectives to your own.

As with any field, analytics has a set of characteristics that can help a person develop into an increasingly better version of themselves. While these characteristics overlap with “virtues” you’ll see in other contexts, these posts are meant to highlight their specific relationship to professional development in this career field.

There seem to be 2 extremes that are too easy to fall into–the first being a self-deprecating beginner sort of mindset where one is unsure about everything and constantly second-guessing solutions, and the other being an overly self-assured mindset, either from lots of experience or a confident beginner who isn’t yet aware of the complexities of the field (for more on this, see the Dunning-Kruger effect). With sufficiently diverse experience, it’s easy to feel that you’ve “seen it all.” In many cases, you have seen a good slice of things, but you haven’t worked on every aspect of an implementation every day – that is simply not possible. No matter what your level of experience, the web analytics stack that surrounds you is constantly evolving, and it’s possible to lose sight of some of the basics or certain aspects of a platform as you narrow your focus for various projects.

This necessitates walking a line where you can be confident in your recommendations, yet open to new information and listening to differing opinions. Since we all can’t be up to date on everything all the time, there is huge benefit in listening to alternative perspectives to your own. That doesn’t mean they’re automatically valid, but allowing the space for them to be aired is supremely valuable, not least of all because it allows you to hone your active listening skills and refine how you can eloquently navigate a set of varied opinions to arrive at a definite project plan.

This can be a hard one to find where the line is, and there are bound to be some times when you veer a bit far to one side or the other of the overconfidence/humility line, but the process of figuring this out is key to continued personal progress. I certainly don’t have everything figured out, but I’ve seen this come up as a recurring theme that can have a big impact. Onward and upward!