Skip to main content

advanced_dom_available
interface

Requires access to the Advanced DOM Events in web pixel app extensions scope. To request access, please use the form in the Partner Dashboard. This scope is only available for apps that have a heatmap and/or session recordings. The Advanced DOM Events cannot be used on custom apps.

The advanced_dom_available event is published when the DOM has been loaded and is available for interaction.

Shopify Plus

This event is limited on checkout to stores on the Shopify Plus plan.

string

The client-side ID of the customer, provided by Shopify

string

The ID of the customer event

string

The name of the customer event.

number

The sequence index number of the event.

string

The timestamp of when the customer event occurred, in ISO 8601 format

.AdvancedDom
Was this section helpful?

Accessing Advanced DOM Events

App Pixel

import {register} from '@shopify/web-pixels-extension';

const voidElements = new Set([
'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'link',
'meta',
'param',
'source',
'track',
'wbr',
]);

const domFragmentMap = new Map();

function buildHtml(fragment) {
const node = fragment.node;

if (!domFragmentMap.has(node.serializationId)) {
domFragmentMap.set(node.serializationId, fragment);
}

// Handle text nodes (nodeType === 3)
if (node.nodeType === 3) {
return node.textContent || '';
}

// Handle document node
if (node.nodeType === 9) {
return fragment.children.reduce(
(html, childFragment) => `${html}${buildHtml(childFragment)}`,
'',
);
}

// Doctype node
if (node.nodeType === 10) {
const attrs = node.attributes;
let html = '<!DOCTYPE';
if (attrs.name) {
html += ` ${attrs.name}`;
}
if (attrs.publicId) {
html += ` PUBLIC "${attrs.publicId}"`;
}
if (attrs.systemId) {
html += ` "${attrs.systemId}"`;
}
return `${html}>`;
}

if (!node.tagName) return '';

// Handle element nodes
const tagName = node.tagName.toLowerCase();
const attributes = Object.keys(node.attributes)
.filter((attr) => node.attributes[attr])
.map((attr) => ` ${attr}="${node.attributes[attr]}"`)
.join('');

// Start tag
let html = `<${tagName}${attributes}${voidElements.has(tagName) ? ' /' : ''}>`;

// Add children recursively
fragment.children.forEach((childFragment) => {
html += buildHtml(childFragment);
});

// End tag
if (!voidElements.has(tagName)) {
html += `</${tagName}>`;
}

return html;
}

register(({analytics}) => {
let root;
analytics.subscribe('advanced_dom_available', (event) => {
root = event.data.root;

// E.g. rebuilds the HTML string of the whole document.
buildHtml(root);
});
});