- Published on
Adding click tracking to shadow DOM web components with Adobe Tags/Launch
- Authors
- Name
- John Simmons
- john@perpetua.digital
The good ole DOM
The DOM used to be a reliable place. Every element on you page could be found within it. Those days are fading, or at least becoming trickier thanks to modern web components and their concept of a shadow DOM. Not to be confused with the shadow realm. Web components are useful, but present a problem for tag managers like Launch that rely on the regular DOM to trigger rules. Lets take a look at a web component that exists in a shadow dom:
Here is the code for the page above. The blue button is a custom defined HTML element known as a web component
<!DOCTYPE html>
<html>
<head>
<title>Buttons</title>
<style>
.button {
width: 200px;
height: 200px;
border: none;
color: white;
font-size: 16px;
font-weight: bold;
text-align: center;
line-height: 100px;
cursor: pointer;
margin: 10px;
}
.regular {
background-color: red;
}
</style>
</head>
<body>
<button id="redButton" class="button regular">Regular DOM Element</button>
<script>
// This is a web component
class ShadowButton extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({ mode: 'open' })
const button = document.createElement('button')
button.setAttribute('id', 'blueButton')
button.setAttribute('class', 'button shadow')
button.setAttribute(
'style',
'width: 200px; height: 200px; border: none; color: white; font-size: 16px; font-weight: bold; text-align: center; line-height: 100px; cursor: pointer; margin: 10px;background-color:blue'
)
button.textContent = 'Shadow DOM Element'
shadow.appendChild(button)
}
}
// Register the web component
customElements.define('shadow-button', ShadowButton)
</script>
<shadow-button class="button shadow"></shadow-button>
</body>
</html>
Everything renders and looks normal, but the issue occurs when you try to select these elements from the DOM.
Where does this cause problems in Launch?
I usually run across this issue when trying to add click tracking to these web components. Just adding a regular Launch click trigger to a rule doesn't work. For example:
Workarounds
So there isn't really an out of the box solution for this in Launch. Maybe someone should make an extension 🤔 Anyway, I really only see 2 options:
- Build a direct call event or datalayer push into the code that builds the web component
- Write custom code in Launch that reaches into the shadow root and adds direct call/datalayer push on the click event
Integrating into the web component
Although web components are special as mentioned above, they are still just regular HTML & JS, and thus, can have event listeners added to them. Because of this, you can bake a direct call or data layer push event right into an event listener. If I wanted to track clicks on the blue button for example:
// ...
button.addEventListener('click', () =>
_satellite.track('shadow element click!!!', { extra: 'data' })
)
shadow.appendChild(button)
or
// ...
button.addEventListener('click', () =>
datalayer.push({ event: 'shadow element click', extra: 'data' })
)
shadow.appendChild(button)
Adding your own event listeners via custom code
This option is less than ideal given that you need to manually traverse into the shadow dom with specific selectors, but nevertheless, it works. In my rule, I'm waiting for the <shadow-button>
element to exist, then reaching into it and adding my own event listener to the #blueButton
web component.
Wrap up
So that is how you can add tracking to a web component element in the shadow dom. In this case, I added click tracking via event listeners, but if you should be able to write any kind of activity tracking needed provided you do it in custom code. If anyone has a better way to do this, please reach out!