Industry Docs Series #1: the Solution Design Reference (the not-so-secret sauce)

33 Sticks Logo- Orange Circle with 3|3 in it

(This is cross-posted from the 33 Sticks blog)

Almost every organization that uses Digital Analytics has some combination of the following documents:

  • Business Requirements Document
  • Solution Design Reference/Variable Map
  • Technical Specifications
  • Validation Specifications/QA Requirements

All of the consulting agencies use them and may even have their own special, unique versions of them. They’re often heavily branded and may be closely guarded. And it can be very difficult to find a template or example as a starting point.

In my 11 years as a consultant who focuses on Digital Analytics implementation, I’ve been through MANY documentation templates. I’ve used the (sometimes vigorously enforced) templates provided by whoever was my current employing agency; I’ve used client’s existing docs; I’ve created and recreated my own templates dozens of times. I’ve used Word documents, Google Sheets, txt/js documents, Confluence/Wiki pages, and (much to my chagrin) Powerpoint presentations (there’s nothing wrong with Powerpoint for presentations, but it really isn’t a technical documentation tool). I’ve in turn shared out templates and examples both within agencies and more broadly in the industry, and I’ve now decided it’s time to stop hoarding documentation templates and examples, and share them publicly in a git repo, starting with the most foundational: the Variable Map (sometimes called a Solution Design Reference, or SDR).

The Variable Map

You may or may not have a tech spec or a business requirements document, but I bet you have a document somewhere that lays out the mapping of your custom dimensions and metrics. Since Adobe Analytics has up to 250 custom eVars, 75 custom props, and up to 1000 custom events, it’s practically essential to have a variable map. In fact, the need for a quick reference is why I created the PocketSDR app a few years ago (shameless plug) so you could use your phone to check what a variable was used for or what its settings are. But when planning/maintaining an implementation, you need a global view of all your variables. This isn’t a new idea: Adobe’s documentation discusses it at a higher level, Chetan Gaikwad covered it on his blog more recently, Jason Call blogged about this back in 2016, Analytics Demystified walked through it in 2015, and even back in 2014, Numeric Analytics discussed the importance of an SDR. Yet if you want a template, example, or starting point, you still generally have to ask colleagues and friends to pass you one under the table, use one from a previous role/org, or you just start from scratch. This is why 33 Sticks is making a generic SDR publicly available on our git repo.

The cats out of the bag

There are various reasons folks (including me) haven’t done this in the past. For practitioners, there is (understandably) a hesitance to share what you are doing- you might not want your brand to be associated with how good/not good your documentation is, and/or you may not want to give your competitors any “help” (more on that in an upcoming podcast). For agencies, there may be a desire to not show “the man behind the curtain”, or they may believe (or at least want their clients to believe) that their documentation is special and unique.

So why am I sharing it?

  • Because I don’t think the format of my variable map is actually all that special- a variable map is a variable map (but that doesn’t mean we should all have to start from scratch every time). This isn’t intended to be the end-all-be-all of SDRs, but rather, as a starting point or an example for comparison. Any aspect of it might be boring/obvious to you, overkill, or just not useful, but my hope is that there is at least a part of it that will be helpful.
  • Because while I DO think I have some tricks that make my SDRs easier to use, I recognize that most of those tricks are things I only know or do because someone in the industry has shared their knowledge with me, or a client let me experiment a bit to find what worked best.
  • Because 33 Sticks doesn’t bill by the hour and I have no incentive to hoard “easy”/low-level tasks from my clients. If a client comes to me and says “I used your blog post to get started on an SDR without you”, I can say, “Great! That leaves us more time to get into more strategic work!”
  • Because where I can REALLY offer value as a consultant isn’t in the formatting/data entry part of creating an SDR, but rather, in the thought we put into designing/documenting solutions, and in how we help clients focus on goals and getting long-term value out of data so they don’t get stuck in “maintenance mode.”
  • And finally, because I’m hoping to hear back from folks and learn from them about what they’re doing the same or differently. We all benefit from opening up about our techniques.

Enough with the pedantry, let’s get back to discussing how to create a good SDR.

SDR Best Practices

It’s vitally important you keep your variable map in a centrally-accessible location. If I update a copy of the SDR on my hard drive, that doesn’t benefit anyone but me, and by the time I merge it back into the “global” one, we may already have conflicts.

It should go without saying, but keeping it updated is also a good idea. I actually view most types of Digital Analytics documentation as fitting into one of two categories: primarily useful at the beginning of an implementation, OR an ongoing, living document. Something like a Business Requirements Document COULD be a living document, but let’s be honest: its primary value is in designing the solution, and it can have a high level of effort to keep it comprehensively up-to-date. Technical specifications for the data layer are usually a one-time deal: after it is implemented, it goes into an archive somewhere. But the simple variable map… THAT absolutely should be kept current and frequently referenced.

Tools for Creation/Tracking

If you’re already using Adobe Analytics, then you probably need to get an accurate and current list of your variables and their settings. Even if you have an SDR, you should check if it matches what’s set up in your Analytics tool. You could always export your settings from within the Admin Console, but I’ve found the format makes the output very difficult to use. I’d recommend going with one of the many other great industry tools (all of which are free):

These tools are great for getting your existing settings, but they don’t leave a lot of room for planning and documenting the full implementation aspects of your solution, so usually I use these as a source to copy my existing settings into my SDR.

What should an SDR contain?

On our git repo, you’ll see an Excel sheet that has a generic example Variable Map. Even if you have an SDR that you like already, take a look this example one- there may be some items you might get use of (plus this post will be much more interesting if you can see the columns I’m talking about).

Pretty much ALL Variable Maps have the following columns (and mine is no different):

  • Variable/Report Name (eg, “Internal Search Terms”)
  • Variable/Report Number (eg, “eVar1”)
  • Description
  • Example Value
  • Variable Settings

But over the years I’ve found a few other columns can really make the variable map much more use-able and useful (and again, this all may make more sense if you download our SDR to have an example):

A “Sorting Order” or Key

If, like me, you love using tables, sorting, and filtering in Excel, you may discover that Excel doesn’t know how to sort eVars, props and events: because it isn’t fully a number or string, it thinks that the proper order is “eVar1, eVar10, eVar2, eVar20”. So if you’ve sorted for some small task and want to get back to a sensible order, you pretty much have to do things manually. For this reason, I have a simple column that has nothing other than numbers indicating my ideal/proper/default order for my table.

Param

This is for those who live their lives in analytics beacons rather than reports, like a QA team. It’s nice to know that s.campaign is the variable, and it is named “Tracking Code” in the reports, but it’s not exactly obvious that if you’re looking in a beacon, the value for s.campaign shows in the “v0” parameter.

Variable Type

Again, I love me some Excel filtering, and I like being able to say “show me just my eVars” or “show the out of the box events”. It can also be handy for those not used to Adobe lingo (“what the heck is an eVar?”). So I have a column with something like the following possible values:

  • eVar- custom conversion dimension
  • event- custom metric (eg “event1”)
  • event- predefined metric (eg “scAdd”, “purchase”)
  • listVar- custom conversion dimension list (eg, “s.list1”)
  • predefined conversion dimension (eg, “s.campaign”)
  • predefined traffic dimension (eg, “s.server”)
  • products string
  • prop- custom traffic dimension

For things like this, where I have specific values I’ll be using repeatedly, I’ll keep an extra tab in the workbook titled “worksheet config”. Then I can use Excel’s “data validation” to pull a drop-down list from that tab.

Category

This is my personal favorite- I use it every day. It’s a way to sort/group variables and metrics that are related to each other- eg, if you are using eVar1, eVar2, prop1, event1, and event2 all in some way to track internal search, it’s nice to be able to filter by this column and get something like this:

The categories themselves are completely arbitrary and don’t need to map to anything outside of the document (though you might choose to use them in your Tech Spec or even in workspaces). Here’s a standard list I might use:

  • Content Identification
  • Internal Search
  • Products
  • Checkout
  • Visitor Segmentation
  • Traffic Sources
  • Authentication
  • Validation/Troubleshooting

Again, I could create/maintain this list in a single place on my “worksheet config” tab, then use “Data Validation” to turn it into a drop-down list in my Variable Map.

Status

This basically answers the question “is this variable currently expected to be working in production?” I usually have three possible values:

  • Implemented
  • Broken (or some euphemism for broken, like “needs work”)
  • In progress

Data Quality Notes

This is for, well, notes on Data Quality. Such as “didn’t track for month of March” or “has odd values coming from PDP”.

Last Validated

This is to keep track of how recently someone checked on the health of this variable/metric. The hope is this will help prevent variables sitting around, unused, with bad data, for months or even years. I even add conditional formatting so if it has been more than 90 days, it turns red.

Scope

Where would I expect to see this variable/metric? Is it set globally? Or maybe it happens on all cart adds?

Description

I’m certainly not unique in having this column, and I’m probably not unique in how many SDRs I’ve seen where this column has not been kept up-to-date. I’d like to stress the importance of this column, though- you may think the purpose of a variable is obvious, but almost every company I’ve worked with has at least one item on their variable map where no current member of the analytics team has any idea what the original goal was.

Ideally, the contents of this column would align with the “Description” setting within the Admin Console for each variable, so that folks viewing the reports can understand how to use the data.

We ARE all setting and using those descriptions, right? RIGHT?

Logic/Formatting and Example Value

Your Variable Map needs to have a place to detail the type of values you’d expect in this report. This:

  • helps folks looking at the document to understand what each variable does (especially if you don’t have stellar descriptions)
  • lets developers/implementers know what sort of data to send in
  • provides a place to make sure values are consistent. For instance, if I have a variable for “add to cart location”, there’s no inherent reason why the value “product details page” would be more correct than “product view”… but I still only want to see ONE of those values in my report. If folks can look in my variable map and see that “product details page” is the value already in use, they won’t go and invent a new value for the same thing).

I often find it a good exercise to run the Adobe Consulting Health Dashboard and grab the top few values from each variable to fill out this column.

Source Type

What method are we using to get the value for the data layer? I usually use Excel Data Validation to create this list:

  • query param
  • data layer
  • rule-based/trigger-based (like for most events, which are usually manually entered into a TMS rule based on certain conditions)
  • analytics library (aka, plugins)
  • duplicate of another variable

Dimension Source or Metric Trigger

This contains the details that complement the “source type” column: If it comes from query parameters, WHICH query parameter is it? If it comes from the data layer, what data layer object is it? If it’s a metric, what in the data layer determines when to fire it (for instance, a prodView event doesn’t map directly to a data layer object, but it does RELY on the data layer: we set it whenever the pageType data layer object is set to “product details page”.)

Variable Settings

This is something many SDRs have but can be a pain to keep consistent, because every variable type has different settings options:

  • events
    • type
      • counter (default)
      • numeric
      • currency
    • polarity
      • Up is good (default)
      • Up is bad
    • visibility
      • visible everywhere (default)
      • builders
      • hidden everywhere
    • serialization
      • always record event (default)
      • record once per visit
      • use serialization ID
    • participation
      • disabled (default)
      • enabled
  • eVars
    • Expiration
      • Visit (default)
      • Hit/Page View
      • Event (like purchase)
      • Custom
      • Never
    • Allocation (note: this is less relevant these days now that allocation can be decided in workspace)
      • Most Recent (last) (default)
      • Original Value (first)
      • Linear
    • Type
      • Text string (default)
      • Counter
    • Merchandising
      • Disabled (default)
      • Product Syntax
      • Conversion Syntax
    • Merchandising Binding Events
  • Props
    • List Prop
      • Disabled (default)
      • Enabled
    • List Prop Delimiter
    • Pathing
      • Disabled (default)
      • Enabled
    • Participation
      • Disabled (default)
      • Enabled

As you can see, you’d have to account for a lot of possible settings and combinations- I’ve seen some SDRs with 30 columns dedicated just to variable settings. I tend to simplify and just have one column where I only call out any setting that differs from the default, such as “Expires after 2 weeks” or “merchandising: conversion syntax, binds on internal search event, product view, and cart add.”

Classifications

This should list any classifications set up on this variable. This is a good one to keep updated, though I find many folks don’t.

GDPR Considerations

Don’t forget about government privacy regulations! Use this to flag items that will need to be accounted for in your privacy policies and procedures. Sometimes merely having the column can serve as a good reminder that privacy is something we need to consider when designing our solution.

TMS Rule and TMS Element

I find these very helpful in designing a solution, but I’ll admit, they often fall by the wayside after an implementation is launched- and I don’t even see that as a bad thing. Once configured, your TMS implementation should speak for itself. (This will be even more true when Adobe releases enhanced search functionality in Launch.)

Other tabs

Aside from the variable map, I try to always have a tab/sheet for a Change Log. If nothing else, this can help with version control when someone had a local copy of the SDR that got off sync from the “official” one. It also lets you know who to contact if you have questions about a certain change that was made. I also use this to flag which changes have been accounted for in the Report suite Settings (eg, I may have set aside eVar2 for “internal search terms”, but did I actually turn it on in the tool?)

If you have many Report Suites, it may be helpful to have a tab that lists them all- their friendly name, their report suite ID, any relevant URLs/Domains, and perhaps the business owner of that Report Suite.

Also, if you have multiple report suites, you may want to add columns to the variable map or have a whole separate tab that compares variables across suites (the Report Suite exporter and the Observepoint SDR Builder both have this built in).

What works for you?

As I said, I don’t think my template is going to be the ultimate, universal SDR. I’d love to know what has worked for other people- did I miss anything? Is there anything I’m doing that I should do differently? Do you have a template you’d like to share? I’d love to hear from you!

New industry tool: Adobe Configuration Export

An industry friend and former coworker, Gene Jones, made me aware of an awesome new tool he’s created- a tool that exports your Report Suite info into an excel file. It can compare the variable settings of multiple report suites in one tab, then creates a tab with a deeper look at all the settings for each report suite.

This is similar to the very handy Observepoint SDR Builder– I’ll freely admit I’m likely to use both in the future. Both (free) tools show you your settings and allow for report suite comparison. The Observepoint SDR Builder uses a google sheet extension and has a little more set up involved (partially because if you’re an Observepoint customer you can expand its functionality) but it can allow you manage your settings directly from the google sheet (communicating those changes back to the Adobe Admin Console).

But sometimes all you want is a simple export of current settings in a simple, local view, in which case the Adobe Configuration Export tool is very straightforward and simple to use.

And, it’s open source– the community can add to it and make use of it for whatever situations they dream up. I’m excited to see what features get added in the future (I see a “Grade Your Config” option that intrigues me). Nice work, Gene!

Adobe Launch’s Rule Ordering is a big deal for Single Page Apps

In November, I posted about some of the ways that Launch will make it easier to implement on Single Page Apps (SPAs), but I hinted that a few things were still lacking.
In mid-January, the Launch team announced a feature I’ve been eagerly awaiting: the ability to order your rules. With this ability, we finally have a clean and easy way to implement Adobe Analytics on a Single Page App.

The historical problem

As I mentioned in my previous post, one of the key problems we’ve seen in the past was that Event-Based Rules (EBRs) and Direct Call Rules (DCRs) can’t “stack”. Let me explain what I mean by that.

Not a single page app? Rule Stacking rocks!

For example, let’s say I have an internal search “null results” page, where the beacon that fires should include:

  • Global Variables, like “s.server should always be set to document.hostname”
  • Variables specific to the e-commerce/product side of my site with a common data layer structure (pageName should always be set to %Content ID: Page Name%)
  • Search Results variables (like my props/eVars for Search Term and Number of Search Results, and a custom event for Internal Searches)
  • Search Results when a filter is applied (like a listVar for Filter Applied and an event for User applied Search Filter)
  • Null Results Variables (another event for Null Internal Searches and a bit of logic to rewrite my Number of Search Results variable from “0” to “zero” (because searching in the reports for “0” would show me 10, 20, 30… whereas “zero” could easily show me my null results)

With a non-SPA, when a new page load loads, DTM would run through all of my page load rules and see which had conditions that were matched by the current page. It would then set the variables from those rules, then AFTER all the rules were checked and variables were set, DTM would send the beacon, happily combining variables from potentially many rules.

Would become this beacon:

If you have a Page Load Rule-based implementation, this allows you to define your rules by their scope, and can really use the power of DTM to only apply code/logic when needed.

Single Page App? Not so much.

However, if I were in a Single Page App, I’d either be using a Direct Call Rule or an Event-Based Rule to determine a new page was viewed and fire a beacon. DCRs and EBRs have a 1:1 ratio with beacons fired- if a rule’s conditions were met, it would fire a beacon. So I would need to figure out a way to have my global variables fire on every beacon, and set site-section-specific and user-action-specific variables, for every user action tracked. This would either mean having a lot of DCRs and EBRs for all the possible combos of variables (meaning a lot of repeat effort in setting rules, and repeated code weight in the DTM library), or a single massive rule with a lot of custom code to figure out which user-action-specific variables to set:

Or leaving the Adobe Analytics tool interface altogether, and doing odd things in Third Party Tag blocks. I’ve seen it done, and it makes sad pandas sad.

The Answer: Launch

Launch does two important things that solve this:

  1. Rules that set Adobe Analytics Variables do not necessarily have to fire a beacon. I can tell my rule to just set variables, to fire a beacon, or to clear variables, or any combination of those options.
  2. I can now order my rules to be sure that the rule that fires my beacon goes AFTER all the rules that set my variables.

So I set up my 5 rules, same as before. All of my rules have differing conditions, and use two similar triggers: one set to fire on Page Bottom (if the user just navigated to my site or refreshes a page, loading a fresh new DOM) and one on Data Element Changed (for Single Page App “virtual page views”, looking at when the Page Name is updated in the Data Layer).

UPDATE: I realize now that you probably wouldn’t want to combine “Page Bottom” and “Data Element Changed” this way, because odds are, it’s going to count your initial setting of the pageName data element as a change, and then double-fire on page load. Either way, it’s less than ideal to use “data element changed” as a trigger because it’s not as reliable. But since this post is already written and has images to go with it, I’ll leave it, and we can pretend that for some reason you wouldn’t be updating your pageName data element when the page initially loads. 

When I create those triggers, I can assign a number for that trigger’s Order:


One rule, my global rule, has those triggers set to fire at “50” (which is the default number, right in the middle of the range it is recommended that I use, 1-100). The rule with this trigger not only sets my global variables, it also fires my beacon then clears my variables:

Most of my other rules, I give an Order number of “25” (again, fairly arbitrary, but it gives me flexibility to have other rules fire before or after as needed). One rule, my “Internal Search: Null Results” rule is set to the Order number “30”, because I want it to come AFTER the “Internal Search: Search Results” rule, since it needs to overwrite my Number of Search Results variable from “0” (which it got from the data layer) to “Zero”.

This gives me a chance to set all the variables in my custom rules, and have my beacon and clearVars fire at the end in my global rule (the rule’s Order number is in the black circles):

I of course will need to be very careful about using my Order numbers consistently- I’m already thinking about how to fit this into existing documentation, like my SDR.

Conclusion

This doesn’t just impact Single Page Apps- even a traditional Page Load Rule implementation sometimes needs to make sure one rule fires after another, perhaps to overwrite the variables of another, or to check a variable another rule set (maybe I’m hard coding s.channel in one rule, and based on that value, want to fire another rule). I can even think of cases where this would be helpful for third party tags. This is a really powerful feature that should give a lot more control and flexibility to your tag management implementation.

Let me know if you think of new advantages, use cases, or potential “gotchas” for this feature!

Followup Post: Allocation in Analysis Workspace

I recently posted about some of the implications and use cases of using Linear Allocation (on eVars) and participation (props/events) and in my research, I thought I had encountered a bug in Analysis Workspace. After all, for this flow:

Page A Page B Page C Page D Newstletter Signup event (s.tl)
prop1
eVar1
events
“Page A”
“Page A”
“event1”
“Page B”
“Page B”
“event1”
“Page C”
“Page C”
“event1”
“Page D”
“Page D”
“event1”
“”
“”
“event2”

I saw this in Reports and Analytics (so far, so good):

But then in Analysis Workspace for that prop, trying to recreate the same report, I saw this, where the props were only getting credited for events that happened on their beacon (none got credit for the newsletter signup):

Basically, I lost that participation magic.

Similarly, for the eVar, I saw this report in Reports and Analytics:

And in Workspace, it behaved exactly like a “Most Recent” eVar:

Again, it lost that linear magic.

Calculated Metrics to the Rescue

With the help of some industry friends (thanks, Jim Kultgen at Kohler and Seth Burke at Adobe) I learned that this is not a bug, necessarily- it’s the future! Analysis Workspace has a different way of getting at that data (one that doesn’t require changing the backend settings for your variables and metrics).
In Analysis Workspace reports, allocation can be decided by a Calculated Metric, instead of the variable’s settings. In the calculated metric builder, you can specify an allocation by clicking the gear box next to the metric in the Calculated Metric Definition:

A Note On “Default” Allocation here

On further testing, in Analysis Workspace, it seems that eVars with the back-end settings of either “Most Recent” and “Linear” allocation are treated the same: both will act like “Most Recent” with a metric brought in, and both will act like “Linear” when you bring in a calculated metric where you specified to have Linear Allocation. One might say, if you use Analysis Workspace exclusively, you no longer would need to ever set an eVar to “Linear”.

“Default” does still seem to defer to the eVar settings when it comes to Most Recent or Original (just not Linear). So in an eVar report where the eVar’s backend setting is “Original”, whether I used my “normal” Newsletter Signups event (column 2), or my Calculated one with Linear Allocation (column 3), credit went to the first page:

So, the Calculated Metric allocation did NOT overwrite my eVar setting of “Original”.

So how do I replicate my Linear eVar report?

To get back that Linear Allocation magic, I would create a new Calculated Metric, but I would specify “Linear Allocation” for it in the Calculated Metric Definitions. Then I can see that linear metric applied to that eVar (the original metric in blue, the new calculated one with linear allocation in purple) :

Note that it’s 40-20-20-20, rather than 25-25-25-25. I’ll admit, this isn’t what I expected and makes me want to do more testing. I suspect that it’s looking at my FIVE beacons (four page views, one success event) and giving that Page D double credit- one for its page view beacon, and one for the success event beacon (even though it wasn’t set on that beacon, it WAS still persisting). So it isn’t perfectly replicating my R&A version of the report, but it is helping me spread credit out between my four values.

And my participation prop?

Similarly, with the prop, when I bring in my new “Linear Allocation” calculated metrics I just set up for my eVar (in blue), I now see it behave like participation for my Newsletter Signup metric, unlike the original non-calculated metrics (in green):

…but those Page View numbers look just like linear allocation in an eVar would (2.08, 1.08, .58, .25), not the nice clean numbers (4, 3, 2, 1) I’d get for a prop with participation. At this point, I still don’t have my Content Velocity prop report, but I’m getting closer.

So how do I get my Content Velocity?

Analysis Workspace has a “Page Velocity” Calculated metric built into its Content Consumption template, which reports the same data as my Content Velocity (participation-enabled) prop did in Reports & Analytics.

 If I want to recreate this calculated metric for myself, I use the formula “Page Views (with Visit Participation)/Page Views”:

Though my friend Jim Kultgen suggested a metric he prefers:

((Page Views 'Visit Participation')/(Visits))-1

This shows you how a page contributed to later page views, discounting how it contributed to itself (because obviously it did that much- every page does), and looking at visits to that page (so repeat content views don’t count for much).

These two calculated metrics would show in an AW report like this:

Conclusion

If I use Analysis Workspace exclusively, I may no longer need to enable participation on metrics or props- I could just build a Calculated Metric off of existing metrics, and change their allocation accordingly, and that would work the same with either my eVars or my Props.

Knowing a few of these quirks and implications, I can see a future with simpler variable maps (no more need for multiple eVars receiving the same values but with different allocation settings) and the ability to change allocation without tweaking the original data set (my “Newsletter Signups” metric retains its original reporting abilities, AND I can build as many Calculated Metrics off of it as I want). I’m excited to see how Adobe will keep building more power/flexibility into Workspace!

Participation and Linear Allocation in Adobe Analytics- behavior I expected, and some I did not

I recently posted about some of the implications and use cases of using Linear Allocation (on eVars) and participation (props/events) and in my research, I thought I had encountered a bug in Analysis Workspace. After all, for this flow:

Page A Page B Page C Page D Newstletter Signup event (s.tl)
prop1
eVar1
events
“Page A”
“Page A”
“event1”
“Page B”
“Page B”
“event1”
“Page C”
“Page C”
“event1”
“Page D”
“Page D”
“event1”
“”
“”
“event2”

I saw this in Reports and Analytics (so far, so good):

But then in Analysis Workspace for that prop, trying to recreate the same report, I saw this, where the props were only getting credited for events that happened on their beacon (none got credit for the newsletter signup):

Basically, I lost that participation magic.

Similarly, for the eVar, I saw this report in Reports and Analytics:

And in Workspace, it behaved exactly like a “Most Recent” eVar:

Again, it lost that linear magic.

Calculated Metrics to the Rescue

With the help of some industry friends (thanks, Jim Kultgen at Kohler and Seth Burke at Adobe) I learned that this is not a bug, necessarily- it’s the future! Analysis Workspace has a different way of getting at that data (one that doesn’t require changing the backend settings for your variables and metrics).
In Analysis Workspace reports, allocation can be decided by a Calculated Metric, instead of the variable’s settings. In the calculated metric builder, you can specify an allocation by clicking the gear box next to the metric in the Calculated Metric Definition:

A Note On “Default” Allocation here

On further testing, in Analysis Workspace, it seems that eVars with the back-end settings of either “Most Recent” and “Linear” allocation are treated the same: both will act like “Most Recent” with a metric brought in, and both will act like “Linear” when you bring in a calculated metric where you specified to have Linear Allocation. One might say, if you use Analysis Workspace exclusively, you no longer would need to ever set an eVar to “Linear”.

“Default” does still seem to defer to the eVar settings when it comes to Most Recent or Original (just not Linear). So in an eVar report where the eVar’s backend setting is “Original”, whether I used my “normal” Newsletter Signups event (column 2), or my Calculated one with Linear Allocation (column 3), credit went to the first page:

So, the Calculated Metric allocation did NOT overwrite my eVar setting of “Original”.

So how do I replicate my Linear eVar report?

To get back that Linear Allocation magic, I would create a new Calculated Metric, but I would specify “Linear Allocation” for it in the Calculated Metric Definitions. Then I can see that linear metric applied to that eVar (the original metric in blue, the new calculated one with linear allocation in purple) :

Note that it’s 40-20-20-20, rather than 25-25-25-25. I’ll admit, this isn’t what I expected and makes me want to do more testing. I suspect that it’s looking at my FIVE beacons (four page views, one success event) and giving that Page D double credit- one for its page view beacon, and one for the success event beacon (even though it wasn’t set on that beacon, it WAS still persisting). So it isn’t perfectly replicating my R&A version of the report, but it is helping me spread credit out between my four values.

And my participation prop?

Similarly, with the prop, when I bring in my new “Linear Allocation” calculated metrics I just set up for my eVar (in blue), I now see it behave like participation for my Newsletter Signup metric, unlike the original non-calculated metrics (in green):

…but those Page View numbers look just Despite clearly remembering learning about it my first week on the job at Omniture in 2006, I realized recently that I did not have a lot of confidence in what participation and linear allocation would do in certain situations in Adobe Analytics. So I put a good amount of effort into testing it to confirm my theories, and I figured I’d pass along what I discovered.

First, the Basics: eVar Allocation

You may already know this part, so feel free to skip this section if you do. Allocation is a setting for Conversion Variables (eVars) in Adobe Analytics, with three options:

Let’s take a simple example to show what how this effects things. Let’s say a user visits my site with this flow:

Page A Page B Page C Page D Form Submit- Signup
s.eVar5=”Page A” s.eVar5=”Page B” s.eVar5=”Page C” s.eVar5=”Page D” s.events=”event1″

Most Recent (Last)

Most eVars have the “defaultiest” allocation of “Most Recent (Last)”, meaning in an event1 report broken down by eVar5, “Page D” would get full credit for the event1 that happened, since it was the last value we saw before event1. So far, pretty simple.

Original Value (First)

But maybe I want to know which LANDING page contributed the most to my event1s (there are other ways of doing this, but for the sake of my example, I’m gonna stick with using allocation). In that case, I might have the allocation for that eVar set to “Original Value (First)” so then “Page A” would get full credit for this event1, since it was the first value we saw for that variable. If my eVar is set to expire on visit, then it’s still nice and straightforward. If it’s set to never expire, then the first value we ever saw for that user will always get credit for any of that user’s metrics. If it’s set to expire in two weeks, then we’ll see the first value that was passed within the last two weeks.

This setting is frequently used for Marketing Campaigns (it’s not uncommon to see s.campaign be used for “Most Recent Campaign in the last 30 days” and then another eVar capture the exact same values, but be set to “Original Campaign in the last 30 days”).

Linear Allocation

If I’m feeling a bit more egalitarian, and want to know ALL the values for an eVar that contributed to success events, I would choose linear allocation. In this scenario, all four values would split the credit for the one event, so they’d each get one fourth of the metric:

(Though it may not actually look like this in the report- by default it would round down to 0. But I’ll talk about decimals later on).

So, that’s allocation.

Then what is participation?

Participation is a setting you can apply to a prop, so that if you bring a Participation-enabled metric into the prop’s report, you can see which values were set at some point before that event took place. Repeat: to see participation you must have a prop that is set to “Display Participation Metrics”:

And the metric you want to see needs to have participation enabled (without this, in the older Reports and Analytics interface, that event won’t be able to be brought into the prop report):

Unlike linear allocation for an eVar, participation for a prop means all the values for that prop get full credit for an event that happened. So, given this flow:

Page A Page B Page C Page D Form Submit- Signup
s.prop1=”Page A” s.prop1=”Page B” s.prop1=”Page C” s.prop1=”Page D” s.events=”event1″

You would see a report like this, because each value participated in the single instance of that event:

New Learnings (for me): Content Velocity

One thing these settings can be used for is measuring content velocity: that is, how much a certain value contributed to more content views later on. For instance, if I have a content site, and I want to know how much one piece of content tends to lead to the reading of MORE content, I might use a participation-metric-enabled prop with a participation-enabled Page View custom event, or I might use an eVar with linear allocation against a Page View custom event (whether or not the event has participation enabled doesn’t matter for the eVar). For my test, I did both:

Page A Page B Page C Page D
s.prop1=”Page 1″
s.eVar1=”Page 1″
s.events=”event1″
s.prop1=”Page 2″
s.eVar1=”Page 2″
s.events=”event1″
s.prop1=”Page 3″
s.eVar1=”Page 3″
s.events=”event1″
s.prop1=”Page 4″
s.eVar1=”Page 4″
s.events=”event1″

The prop

The prop version of this report would show me that Page 1 contributed to 4 views (its own, and 3 more “downstream”). Whereas Page 2 contributed to 3 (its own, and two more downstream), etc…

The eVar

Alternatively, the eVar would show me some thing pretty odd:

Those weird numbers don’t make sense on this small scale (how could 0 get 6.3%?), because it is rounding, and not showing me decimals. If I want to see the decimals, I can create a really simple calculated metric that brings in my custom Page View event (event1) and tells it to show decimals:

The report then makes a little more sense and show us where the rounded numbers came from (and how Page 4, with “0” Page Views, got 6.3% of the credit), but may still seem mysterious:

Those are some odd numbers, right? Here’s the math:

 Value Credit Why?   Explanation
Page 1 2.08 1+0.5+0.33+0.25 It got full credit for its own view, then half the credit (shared with page 2) for the event on Page 2, then a third of the credit (shared with Page 2 and Page 3) on Page 3…
Page 2 1.08 0.5+0.33+0.25 It only got half credit for the event that took place on its page (shared with Page 1), then a third of the credit (shared with Page 1 and Page 3) on Page 3, etc…
Page 3 0.58 .33+.25 It only gets a third of the credit that took place on its page, and a quarter of the credit for the fourth page.
Page 4 0.25 0.25 The event that happened on this page is shared with all four pages.

Crazy, right? I’m not going to tell you which an analyst should prefer, but as always, you should ask the question: “What will you DO with this information?”

What happens when multiple values appear in the same flow?

Let’s say the user does something like this, where they hit one value a couple page views in a row (Page B in this example), or they hit a value 2 separate times (Page A in this example):

Page A Page B Page B
(again)
Page C Page D Page A
(again)
Conversion event
prop1
eVar1
events
“Page A”
“Page A”
“event1”
“Page B”
“Page B”
“event1”
“Page B”
“Page B”
“event1”
“Page C”
“Page C”
“event1”
“Page D”
“Page D”
“event1”
“Page A”
“Page A”
“event1”
events=”event2″

For the prop, it’s pretty straightforward. This will look like 6 event1s, where Page A gets value for all 6, and Page D gets credit for just 2 (itself, and the Page A that came afterwards):

For the eVar, it gets a little more complicated (I added in a calculated metric so you can see the decimals). Page A (accessed twice at separate times) got double credit for the conversion (which I might have predicted), but Page B (accessed twice in a row) ALSO gets double credit for the conversion (which I didn’t predict, probably because I’m too used to thinking in terms of the CVP plugin):

Caveats

A couple things to be aware of:

  • Settings for participation and allocation don’t apply retroactively- you can’t apply them to existing data. If you want to start using it, you need to change your settings and you’ll see it applied to future data. However, this can mess with existing data, so be careful.
  • Analysis Workspace does some unexpected behavior for both participation and allocation. I’ll have a followup post on that.

Conclusion

Both participation and linear allocation aren’t used often, but they can uniquely solve some reporting requirements and can provide a lot of insight, if you know how to read the data. I hope my experimentation and results here help make it clearer how you might be able to use and interpret data from these settings. Let me know if you have other use cases for using these settings, and how it has worked out for you!like linear allocation in an eVar would (2.08, 1.08, .58, .25), not the nice clean numbers (4, 3, 2, 1) I’d get for a prop with participation. At this point, I still don’t have my Content Velocity prop report, but I’m getting closer.

So how do I get my Content Velocity?

Analysis Workspace has a “Page Velocity” Calculated metric built into its Content Consumption template, which reports the same data as my Content Velocity (participation-enabled) prop did in Reports & Analytics.

 If I want to recreate this calculated metric for myself, I use the formula “Page Views (with Visit Participation)/Page Views”:

Though my friend Jim Kultgen suggested a metric he prefers:

((Page Views 'Visit Participation')/(Visits))-1

This shows you how a page contributed to later page views, discounting how it contributed to itself (because obviously it did that much- every page does), and looking at visits to that page (so repeat content views don’t count for much).

These two calculated metrics would show in an AW report like this:

Conclusion

If I use Analysis Workspace exclusively, I may no longer need to enable participation on metrics or props- I could just build a Calculated Metric off of existing metrics, and change their allocation accordingly, and that would work the same with either my eVars or my Props.

Knowing a few of these quirks and implications, I can see a future with simpler variable maps (no more need for multiple eVars receiving the same values but with different allocation settings) and the ability to change allocation without tweaking the original data set (my “Newsletter Signups” metric retains its original reporting abilities, AND I can build as many Calculated Metrics off of it as I want). I’m excited to see how Adobe will keep building more power/flexibility into Workspace!

Quick poll: What should I tackle next?

Each new year, I tend to dive into some new side project (this is how the Beacon Parser and the PocketSDR came about). I have quite a few things I want to tackle right now, and one main thing I’m slowly plugging away at, but in the meantime, I’m wondering what to prioritize. So, a poll:

Any other ideas (or desired improvements to existing tools)? Let me know in the comments.

Why (and why not) use a Data Layer?

What’s a Data Layer?

Tag Management Systems can get data a variety of ways. For instance in DTM you can use query string parameters, meta tags, or cookie values- but in general, data for most variables comes from one of two sources:

  • To really take advantage of a tag management system like DTM, I may choose to scrape the DOM. I’m gonna call this the MacGyver approach. This uses the existing HTML and styles on a site to For instance, DTM could use CSS selectors to pull the values out of a <div> with the class of “breadcrumb”, and end up with a value like “electronics>televisions>wide-screen”. This relies on my site having a reliable CSS structure, and there being elements on the page that include the values we need for reporting.
  • If I want even more flexibility, control and predictability, I may work with developers to create a data layer. They would create a JavaScript object, such as “universal_variable.pageName”, and give it a value based on our reporting needs, like “electronics | televisions | wide-screen > product list”. This gives greater control and flexibility for reporting, but requires developers to create JavaScript objects on the pages.

Conceptually speaking, a data layer is page-specific (but tool-agnostic) metadata that describes the page and the actions a user may take on it. Practically speaking, a data layer typically consists of a JavaScript object that contains all of the values we’d want to report on for a given page or user.

Data layers are important because they save developers time by allowing them to abstract out the metadata into a tool-agnostic syntax that a TMS like DTM can then ingest and set as data elements. Whereas once I would have told IT “please set s.prop5 and s.eVar5 to the search term on a search results page, and set s.events to event20” now I can just say “please put the search term in a javascript object such as digitalData.page.onsiteSearchTerm and tell me what object it is.” Then the TMS administrators could easily map that to the right variables from there.

You can see an example data layer if you’d like, or you can pull open a developer console for this very blog and look at the object “digitalDataDDT” to see the data layer that is automatically created from Search Discovery’s wordpress plugin.

Why a Data Layer?

My friends at 33 Sticks also have a great blog post on the subject, but I’ll list out some of the reasons I prefer clients to use a Data Layer. To me, it’s an upfront investment for a scalable, easily maintained implementation going forward. It does mean more work upfront- you have to first design the data layer to make sure it covers your reporting requirements, then you’ll need developers to add that to your site. But beyond those upfront tasks, configuration in your TMS will be much simpler, and it will save you many hours of CSS guess work and DOM scraping, and it may prevent broken reporting down the line.

    Upfront LOE Maintenance LOE
Route Amount of Control Dev Analytics Dev Analytics
Old fashioned “page on code” Medium Heavy Heavy Heavy Heavy
DTM + “Macgyver” Low Minimal Heavy Minimal Heavy
DTM + Data Layer High Heavy Medium Minimal Minimal

Another potential benefit to a Data Layer is that more and more supplementary tools know how to use them now. For instance, Observepoint’s site scanning tool can now return data on not just your Analytics and Marketing beacons, but on your Data Layer as well. And one of my favorite debugging tools, Dataslayer, can return both your beacons and your data layer to your console, so if something is breaking down, you can tell if it’s a data layer issue or a TMS issue.

Ask Yourself

Below are some questions to ask yourself when considering using a data layer:

How often does the code on the site change? If the DOM/HTML of the site changes frequently, you don’t want to rely on CSS selectors. I’ve had many clients have reports randomly break, and after much debugging we realized the problem was the developers changed the code without knowing it would affect analytics. It’s easier to tell developers to put a data layer object on a page then leave it alone, than it is to tell them to not change their HTML/CSS.

How CSS-savvy is your TMS team? If you have someone on your team who is comfortable navigating a DOM using CSS, then you may be able to get away without a data layer a little more easily… but plan on that CSS-savvy resource spending a lot of time in your TMS.  I’ll admit, I enjoy DOM-scraping, and have spent a LOT of time doing it. But I recognize that while it seems like a simple short-term fix, it rarely simplifies things in the long run.

How many pages/page types are on the site? A very complicated site is hard to manage through CSS- you have to familiarize yourself with the DOM of every page type.

How are CSS styles laid out? Are they clean, systematic, and fairly permanent? Clearly, the cleaner the DOM, the easier it is to scrape it.

How often are new pages or new site functionality released? Sites that role out new microsites or site functionality frequently would need a CSS-savvy person setting up their DTM for every change. Alternatively, relying on a data layer requires a data-layer-savvy developer on any new pages/site/functionality. It is often easier to write a solid Data Layer tech spec for developers to reference for projects going forward than to figure out CSS selectors for every new site/page/functionality.

How much link-tracking/post-page-load tracking do you have on your site? If you do need to track a lot of user actions beyond just page loads, involving IT to make sure you are tracking the right things (instead of trying to scrape things out of the HTML) can be extremely valuable. See my post on ways to get around relying on CSS for event-based rules for more info on options.

What is the turn-around time for the developers? Many clients move to DTM specifically because they can’t work easily within their dev team to set up analytics. A development-driven data layer may take many months to set up, stage, QA, and publish. Then if changes are needed, the process starts again. It may be worth going through the lengthy process initially, but if changes are frequently needed in this implementation, you may find yourself relying more on the DOM.

Are there other analytics/marketing tag vendors that may use a data layer? You may be able to hit two birds with one stone by creating a data layer that multiple tools can use.

Have you previously used another tag management system? Often, a data layer set up for a different tool can be used by DTM. Similarly, if the client ever moves away from DTM, their data layer can travel with them.

Does the site have jQuery? The jQuery library has many methods that help with CSS selectors (such as .parent, .child, .closest, .is, .closest…). A CSS-selector-based implementation may be more difficult without jQuery or a similar javascript library.

Who should create my Data Layer?

Ideally, your data layer should be created by your IT/developers… or at bare minimum, developers should be heavily involved. They may be able to hook into existing data in your CMS (for instance, if you use Adobe Experience Manager you can use the Context Hub as the basis for your data layer), or they may already have ideas for how they want to deploy. Your data layer should not be specific to just your Analytics solution; it should be seen as the basis of all things having to do with “data” on your site.

Yet frequently, for lack of IT investment, the analytics team will end up defining the data layer and dictating it to IT. These days, that’s what most Tech Specs consist of: instructions to developers on how to build a data layer. Usually, external documentation on data layers (like from consulting agencies) will be based on the W3C standard.

The W3C (with a task force including folks from Adobe, Ensighten, Microsoft, IBM…) has introduced a tool-agnostic data layer standard that can be used by many tools and vendors. The specifications for this can be found on the W3C site, and many resources exist already with examples. Adobe Consulting often proposes using the W3C as a starting point, if you don’t have any other plans. However, in my experience, generally that W3C is just a starting point. Some people don’t like the way the W3C is designed and most everyone needs to add on to it. For example, folks might ask:

  • why is “onsiteSearchTerms” part of digitalData.page? Can I put it instead in something I made up, like digitalData.search?
  • I want to track “planType”- the W3C didn’t plan for that, so can I just put it somewhere logical like digitalData.transaction?
  • I don’t need “digitalData.product” to be in an array- can I just make that a simple object.

The answer is: yes. You can tweak that standard to your heart’s delight. Just please, PLEASE, document it, and be aware that some tools will be built with the official standard in mind.

The Phased Approach

Many folks adopt a TMS specifically because they don’t want to have to go through IT release cycles to make changes to their implementation. You can still use a TMS to get a lot of what you need for reporting without a data layer and without a ton of CSS work. It may be worthwhile to put a “bare minimum” TMS deployment on your site to start getting the out of the box reports and any reports that don’t require a data layer (like something based on a plugin such as getTimeParting), then to fill in the data layer as you are able. I’d be wary though, because sometimes once that “bare minimum” reporting is in place, it can be easy to be complacent and lose some of the urgency behind getting a thorough solution implemented correctly from the start.

Conclusion

I fully understand that a properly designed data layer is a lot of work, but in my experience, there is going to be a lot of effort with or without a data layer- you can choose for that effort to be upfront in the planning and initial implementation, or you can plan on more longterm maintenance.

Find the total number of values in an Adobe Analytics Variable Report

“How do I know how many rows/unique values are in my eVar report?”
I hear this question fairly often, and since the answer isn’t currently extremely straight-forward, I figured I could walk through the solution here. So let’s say you have a report with many pages:
reportPagination
Rather than trying to get to the last page of the report somehow to see how many row numbers there are, you can find out about the number of unique values in the report using the Row Count calculated metric.
To set this up, go to add a metric to the report, then “Add” to get to the Calculated Metric wizard:
addCalcuatedMetric

Give the metric an intuitive name, like “Report Rows” or “Unique Reported Values”, then search in the formulas for “Row Count”:
rowCount

Drag “Row Count” over to the Calculated Metric Definitions, and save. That’s all there is to it!

RowCountCalc

Now you can have that as a metric in your report. For whatever reason, it doesn’t always show nicely if it is the ONLY metric selected, so I recommend having at least one metric (like visits) alongside it as well. It doesn’t make a ton of sense in the report, line-by-line: every line will show the same number, and that number represents the aggregate number of values in the report. So in the below, I can see this particular report has 140 unique rows/values in it:
RowCountReport

I do believe in the future, a simpler way of doing this may be a bit more built in, but for now, here is a relatively easy way to get a count of values for a report!

How to approach Product Finding Methods

Product Finding Method (PFM) is a valuable custom report used by online retailers to tie Cart Adds and eventual Revenue to how users found the product. Unfortunately, these reports are often poorly configured or misunderstood. It is one of the best use cases for using the Merchandising setting on an eVar, but Merchandising, as a concept, is one of the more complicated topics in implementation.

Primer on Merchandising

In order to tie that PFM value to an individual product, and not the overall visit or visitor, we need to use Merchandising. And since we may not know the eventual product at the time that we know the finding method (for instance, if a user is using internal search, at the time we know they are searching, we don’t know what product they’ll eventually land on), we need to use Conversion Syntax- meaning we set it like a typical eVar (instead of in the products string) but have to configure at what point that eVar should be tied (or “bound”) to a product. Take the following user experience into consideration, where eVar5 is used for Product Finding Methods:

PFMflow

In the above, if I did NOT use Merchandising, my report might look like this, where External Campaign gets credit for everything up until it gets overwritten by Internal Search– at which point Internal Search gets credit for everything, including the entire Purchase event.

PFMnoMerchReportIf I DO use Merchandising, the External Campaign gets credit for whatever happens to the product it was bound to- in this case, the Blue Wug. Then Internal Search gets bound to the Red Wug, and gets credit for whatever happens to the Red Wug product:

PFMwMerchReport

We have to be very careful with the binding events (the event that tells Adobe to take whatever value we currently have floating around for that eVar and stick it to the current product), though- merchandising eVars won’t get credit for anything that happens if they are not bound to any product, or if that product isn’t currently present. For instance, in the example above, if you pulled in Internal Searches as a metric in that report, you’d see no PFMs were getting credit for the Internal Search event- even though eVar5 is set on the same page as our search event. That’s because that “Internal Search” value for eVar5 is waiting until a “binding event” to attach it to a product before it will get credit for any metrics, and the “External Campaign” value for eVar5 only gets visibility into things that happen to the product it’s bound to (Blue Wug). No products on the Internal Search page means Conversion-Syntax Merchandising eVars get no credit for the Search event.

How to Plan Your Product Finding Methods

To design your PFM solution, start by thinking of the different ways a client can add an item to their cart. We’ll call these “add to cart location” and give that its own eVar. Typical scenarios are:

  • product details page
  • quick view
  • from wishlist
  • from order history
  • recommendation/cross sell modules

Next, figure out all the ways a user could get to any of those above scenarios. These are Product Finding Methods and should get their own eVar. Typical PFMs include:

  • internal search
  • external site (referrerss and natural search)
  • external campaigns (that take the user directly to the PDP)
  • internal promotion (eg, homepage hero banner)
  • browse (naturally navigating through the menu or breadcrumbs)
  • cross-sell
  • recommendations
  • wishlist
  • order history 

You’ll notice some of your cart add locations may also be product finding methods- that’s ok. Note that Products Detail Page is NOT a PFM- the Product Details page is specific to the product, which is the thing being found not the thing doing the finding.

Both of these eVars will need to be set up for Merchandising (this is set in the Admin console>Report Suites>Edit Settings>Conversion>Conversion Variables). For the Add to Cart Location eVar, since we know the product at the time we know the add to cart location, you can use “product syntax”.

eVar4PFM

This is preferable because it leaves little room for error and has the easiest configuration. Let’s say I’ve set eVar4 to be my “Add to Cart location” eVar. At the time my user adds any item to their cart, I would set eVar4 (often, you can just set it to the current page’s page type):

s.products=";sku1;;;;eVar4=PDP"
s.events="scAdd"

But for Product Finding Method, you often don’t know what product the value for our eVar will eventually bind to, so we need to set it to conversion syntax, and we need to carefully consider which events should bind the current PFM value to the current product. Generally, Product View (ideally a custom event, not prodView) and Cart Add suffice as binding events.

eVar5pfm

DO NOT set to bind on ALL events, as many events happen on your site where your PFM eVar doesn’t have a desirable value.

Next, to implement, we need to figure out where to set each of our PFM values. If you’re using a tag management system like DTM, you can often just piggy back on existing rules for many of your finding methods, but others may need to live in global logic (like in your s_code). See below for a possible configuration.

internal search Set on internal search results page
external site Set in global logic- if no other PFM is present, and the user came from a domain other than your own
external campaigns Set in global logic, if s.campaign is set
internal promotion Set in global logic, if internal campaign eVar is set (or internal campaign query string parameter is present).
browse Set on all Product List Pages and Category pages
cross-sell Set when user clicks or clicks through on a cross-sell module
recommendations Set when user clicks or clicks through on a recommendation module
wishlist Set on Wish List page
order history Set on Order History page

Some folks manage PFM entirely in their s_code or in their (global DTM tool settings) based on whether other variables have been set (“if internal search term eVar has a value, set eVar5 to ‘internal search”‘). For instance, one client has something similar to this, in addition to setting their PFM eVar directly on certain pages (like their List Pages and Category pages, or certain microsites):

//easy way to get just the hostname of the referring site
   var a=document.createElement('a');
   a.href=document.referrer;
   s.refDomain=a.hostname;

if(!s.eVar5){ //if PFM not currently set on the page
   if(s.campaign){s.eVar5="campaign"} 
   else if(s.eVar10){s.eVar5="internal search"}
   else if(s.eVar23){s.eVar5="recommended product"} 
   else if(s.pageName=="My Account>Wishlist"){s.eVar5="my wishlist"}
   else if(document.referrer==""){s.eVar5="direct or bookmarked"}
   else if(s.refDomain.indexOf("mydomain.com")==-1){s.eVar5="external site"} 
 }
   else if(s.eVar15){s.eVar26="internal campaign"} 
}

Conclusion

Hopefully, this gives some ideas and examples for how to get valuable reporting on how users are finding and purchasing products on your site. I’d love to hear about potential scenarios or solutions I’ve missed!

How do I use DTM for a Single Page App?

The question of how to use DTM on Single Page Apps (SPAs) is a VERY hot item right now. By Single Page App, I’m referring to a full user flow contained on a single web page, so as to provide the user a more seamless experience. Often, these pages act like typical web pages, but they don’t always change URLs or load new resources. Many common web development technologies, such as Angular.js, Ember.js, and AJAX use SPA principles.

Unfortunately, there isn’t a single great answer for how to deploy DTM- it depends on many things. I’ll work through some of the options and the limitations to be aware of.

Suppressing Page View Beacons

Whatever method you take for tracking page views in a SPA, keep in mind most SPAs do have one true “page view” when the DOM first loads. If you are going strictly with the DCR or EBR route, you may need to suppress the initial page view beacon the Analytics tool will want to set by default. Otherwise, in the example below where the developers are firing a direct call rule on all page views, you’d get TWO beacons on the first page and 1 on all subsequent pages.

Picture1

Data Layer Considerations

You’ll need to make sure that whatever the sources of your Data Elements are (CSS selector, javascript objects, cookies…) have the correct values BEFORE your rule is triggered. I have an example site showing one way you might do this for a data layer (though you’ll need to look in the source code), but ultimately it’s going to depend on your site.

Variable Persistence

One last consideration is that once your Analytics object exists (as in, the “s” in “s.pageName”), variables set on it will continue to exist unless specifically overwritten. In most cases, you’d overwrite s.pageName with a new value so it isn’t a problem, but something like s.eVar5 may be set on the first beacon in your SPA, and not desired on subsequent beacons. You can use s.clearVars() to “refresh” your “s” object, but you have to make sure it fires at the right time- for example, after the beacon on Page A, but before DTM starts mapping Data Elements to variables for the beacon on Page B. How you do this will depend on the overall deployment method you choose.

Deployment Methods

1) Direct Call Rules

Perhaps the most straight-forward approach is to have developers fire a Direct Call Rule, like _satellite.track(“page view”) on every thing YOU consider a page view, whether it’s a fresh new DOM or not.

Advantages: Disadvantages: 
  • You have ultimate control over when a page view in considered a page view.
  • If you need to clear out variables between beacons (for instance, you set s.eVar5 in the first beacon in the SPA, and don’t want it in the second beacon), Direct Call Rules don’t provide a great place to use something like s.clearsVars(). There are some potential work-arounds, but none are ideal.
  • Developers need to add more DTM-specific code (satellite.track) to your pages.
  • Direct Call Rules don’t allow for extra conditions (like “fire THIS logic on pageA, and THAT logic on pageB”) in the interface.
  • Direct Call Rules don’t “stack”- if multiple rules have conditions that are met, multiple rules will fire.

2) pushState or hashChange

Many SPA frameworks, like Angular, use a certain flag to let the browser know the user is viewing a new “page”.

pushState

DTM can listen for this flag in an Event Based Rule using a pushState or hashChange condition.

ADVANTAGES: DISADVANTAGES: 
  • No additional code is needed- most SPA frameworks are already firing something DTM can listen to
  • It’s an Event Based Rule, which allows you to fire clearVars(), and set extra conditions
  • Because you are listening for an event set by the framework, you have less control over timing. Updating a data layer BEFORE the “pushState” event is detected would be critical.
  • Event Based Rules don’t “stack”- if multiple rules have conditions that are met, multiple rules will fire.

3) Custom Event EBR

Another option, which feels a bit like a blend of the first two options, is to use a Custom Event-based Event Based Rule (and no, that’s not a typo- it’s an EBR based on the JavaScript Concept of a Custom Event). It’s possible Developers are already using this Custom Event concept for their own code and purposes, and DTM can just listen for it… or you can have developers set one specific to our DTM needs by using something like my digitalData.userAction hack.

ADVANTAGES: DISADVANTAGES: 
  • You have a little more control over timing
  • It’s an Event Based Rule, which allows you to fire clearVars(), and set extra conditions
  • May require more developer work- similar level of effort as DCRs
  • Event Based Rules don’t “stack”- if multiple rules have conditions that are met, multiple rules will fire.

 4) (NEW OPTION!) “dataelementchanged” Event Based Rule

Just in the last few weeks, a new option emerged as part of the AEM Context Hub integration. This allows DTM to listen for changes to certain data elements- for instance, you could have a rule fire whenever the “pageName” has changed. My friends at 33 sticks have a great blog post about this already for more info.

ADVANTAGES: DISADVANTAGES: 
  • You have a little more control over timing
  • It’s an Event Based Rule, which allows you to fire clearVars(), and set extra conditions
  • Requires careful consideration of when the data layer changes/loads
  • Event Based Rules don’t “stack”- if multiple rules have conditions that are met, multiple rules will fire.