Using a CEDDL Data Layer with DTM

I feel that standards are a good thing. I think that each of us should strive to follow standard approaches, because it’ll make all of our lives easier. I also think that a Data Layer is an adornment on every site, and a svelte way of helping analysts and marketing do their work more flexibly.

Since December 2013, there is a standard, published by the W3C, called Customer Experience Digital Data Layer, or CEDDL. You can get the PDF from the W3C, if you want to learn about it.

Since pretty much every vendor in this world has also come up with their own standard (including Adobe with the ContextHub on AEM), the question is: why should I use CEDDL? The most important reason to me is: CEDDL is vendor-agnostic.

So today, let’s look at the best way to use CEDDL along with DTM, shall we?


First thing to do is to add the “AEM ContextHub” tool to your DTM Web Property.

Adding the tool means there’ll be a new Data Element type called “AEM ContextHub” in DTM. Those DEs allow your friendly marketer to select the data they want in a DE from a drop down, which is populated from the structure of the Data Layer.

By using those DEs, plus the “dataelementchanged” trigger, you can create Event-based Rules that fire when some (definable) part of the Data Layer changes, perfect for the event structure in CEDDL.

The ContextHub tool was originally designed to work with the AEM ContextHub, as the name suggests. Luckily, the tool is flexible enough to work with any data layer structure, as long as you have a JSON Schema that describes your DL.

For CEDDL, you can find the schema (as you can so many other things) on github: CEDDL JSON Schema.

So let’s do this!

Start by clicking the “Add Tool” button on the “Overview” tab of your Web Property.

Select “AEM ContextHub” from the drop down (it should actually be selected), give your tool a name (like “Data Layer”), then click the “Create Tool” button.

Create Tool Step 1 – Type & Name
On the AEM ContextHub Settings screen, you can decide whether you want to use the default AEM ContextHub data layer, or another structure. We’ll go for the latter, so select “[x] Customize ContextHub Data Layer”, tell it where to find the DL by typing window.digitalData into the “Data Layer Root” field, then click the “Open Editor” button.

Create Tool Step 2 – Structure
You’ll see a mostly black editor window with some code in it.

Editor with AEM ContextHub Schema
That code is the AEM data layer schema, and we need to replace it with a CEDDL-compatible schema.

Press CTRL-A or Command-A to select all code in the editor,

Code Editor – selected
then hit your Backspace or Delete key.

Code Editor – empty
Cool. We want that editor empty. Nice.

Next, get a CEDDL schema. There is one available on mkohlmyr’s github. You can jump straight to the raw code, then select all (CTRL-A on Windows, Command-A on Mac) and copy the lot (CTRL-C or Command-C).

Raw Schema, selected
Back in DTM, paste the schema code into the editor window (CTRL-V or Command-V).

Code Editor with CEDDL Schema
Save the Tool, and we’re done here.

Data Elements

Now that we have the tool, we can use it to more easily define Data Elements.

As an example, let’s build a “Pagename” DE.

Head over to the “Rules” tab, then click “Data Elements” on the left. Now use the “Create Data Element” button.

Create Data Element – step 1
Give your DE a name, say “Pagename”, then select “AEM ContextHub” in the Type drop down.

Create Data Element – step 2
The dialog changes slightly now.

Note that there are two new drop down in the dialog window now:

  1. Source — if you have multiple DLs on your site (totally possible), this one lets you choose one of them
  2. Object — this drop down is where you pick an element from the DL, say page.pageInfo.pageName

The “Object” drop down is what links the DE to the DL.

Create Data Element – step 3
So select “page.pageInfo.pageName”, and you’re done.

Create Data Element – step 4


CEDDL contains a sub-structure called “event”, which is meant to be dynamically populated as things happen on an already loaded page.

You’ll use this for cart adds, email address submits, tab switches within the page, and other user activity, but also for Javascript-driven content changes.

Each time something happens, there’ll be one more event added to the DL, along with some meta data that explains what happened.

For a cart add, as an example, that meta data would be a product ID, quantity, and maybe other data. For a login, it could be simply whether the login was successful, or why not, and so on.

We build a Data Element that points to the event part of the DL, then we have an EBR listen to changes of that DE.

That allows us to properly handle interaction and dynamic changes on any page. Whether the EBR collects all data, determines the right events and “variables”, and tracks directly, or whether it works as a dispatcher, calling other EBRs or DCRs, is entirely up to you.

Event-based Rule for handling CEDDL events
And that’s it. That’s how you use CEDDL with DTM.

(Btw: I think this article might be used beyond the usual developer audience, so that’s why I specified how to select, copy, and paste. HTH)

18 thoughts on “Using a CEDDL Data Layer with DTM

      1. Numeric2

        Sure, websites range massively in their requirements for data layers. The W3C Standard is a good place to start but might require quite a bit of modification in order to be properly scalable to enterprise organisations and websites—of course you might disagree but I wondered what your opinion is.


      2. You’re right, people will modify and amend the standard structure to meet their needs.

        I guess the good thing is that you can, plus other Data Layers need to be amended / modified, too. I don’t think there’s any DL out there that covers everything. So this is neither a pro nor a con for this specific structure.

        And I don’t think it is a reason NOT to use a DL, either. Especially if you have a complex requirement, modelling that via a DL means it is made explicit, which can only be good.

        What are your thoughts?


      3. Numeric2

        I agree, I thinks there’s a quite a bit of custom DL design going on in the industry too, right from the ground up and often done by a FED rather than an Analytics Developer.

        Often this is at the expense of optimisation and personalisation tools which can really flex their muscles when supercharged with a good data layer.


  1. Kevin

    Hi all, i’m a little stuck with setting up the schema to match my existing digitalData object – specifically where I have arrays.

    Here’s how my digitalData model looks in pure JS:

    digitalData = window.digitalData || {};
    digitalData.user = window.digitalData.user || [];
    digitalData.user[0] = window.digitalData.user[0] || {};
    digitalData.user[0].profile = window.digitalData.user[0].profile || {};
    digitalData.user[0].profile.profileInfo = window.digitalData.user[0].profile.profileInfo || {}; = || {}; = || {}; = || {}; = || []; = || {};

    note that scope is an array with two objects inside.

    Would anyone be able to assist me with getting the right CEDDL schema for my configuration?

    Any help appreciated! 🙂


      1. Kevin

        Thanks Jan, very helpful! I guess i’m just having some issues with modifying the CEDDL schema to match my existing digitalData object. I just can’t get the arrays to work for some reason, everything else is fine.


      2. How have you done it? Here’s what I did: copy your code, paste it into my browser console on an empty page. That created a digitalData object for me. Then I used JSON.stringify(digitalData) to get it as a string. I copied that string (minus the surrounding “) into the site I quoted before and hit “Generate”.


  2. Kevin

    Yes, that’s what I did however when I go to create a data element in Adobe DTM, and choose “AEM ContextHub” as the type, i’m limited for the “user” scope.

    Here’s a screenshot of what I see:


      1. Ah. I think that is normal.

        Since an array can have 0 to many elements, and since for a specific part of the element, you have to specify the index, you’ll have to build custom JS Data Elements.

        My suggestion: build a DE that retrieves “user”, then build DEs that retrieve individual parts of the user by first reading the other DE (using _satellite.getVar(‘user’)), then checking everything is available, then output the part you need.

        Does that make sense?


  3. Kevin

    Yes, definitely makes sense! I think i’m going to restructure my digitalData object slightly and drop the array from the “user” scope as it seems pointless anyway (i inherited, not designed, the digitalData config here at work lol).


  4. Pingback: Launch Extensions – Overview – Web Analytics for Developers

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s