Skip to main content

advanced_dom_changed
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_changed event is published when the DOM has been changed in any way, such as an element being added, removed, or modified.

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 domFragmentMap = new Map();

register(({analytics}) => {
let root;

// Get the root node when it becomes available.
analytics.subscribe('advanced_dom_available', (event) => {
root = event.data.root;
});

// Keep the domFragmentMap up to date for reference with other events.
analytics.subscribe('advanced_dom_changed', (event) => {
// Handle added fragments
event.data.addedFragments.forEach((addedFragment) => {
const parentFragment = domFragmentMap.get(
addedFragment.parentSerializationId,
);
if (parentFragment) {
// Find the correct insertion index based on prevSiblingSerializationId
// Default to end if no prev sibling found
let insertIndex = parentFragment.children.length;
if (addedFragment.prevSiblingSerializationId !== -1) {
const prevSiblingIndex = parentFragment.children.findIndex(
(childFragment) =>
childFragment.node.serializationId ===
addedFragment.prevSiblingSerializationId,
);
// Insert after the previous sibling
insertIndex = prevSiblingIndex + 1;
}
// Insert at the calculated index
parentFragment.children.splice(insertIndex, 0, addedFragment);
domFragmentMap.set(addedFragment.node.serializationId, addedFragment);
}
});

// Handle removed nodes
event.data.removedNodes.forEach((removedNode) => {
const removedFragment = domFragmentMap.get(removedNode.serializationId);
const parentFragment = domFragmentMap.get(
removedFragment.parentSerializationId,
);
if (parentFragment) {
parentFragment.children = parentFragment.children.filter(
(childFragment) =>
childFragment.node.serializationId !== removedNode.serializationId,
);
domFragmentMap.delete(removedNode.serializationId);
}
});

// Handle modified nodes
event.data.modifiedNodes.forEach((modifiedNode) => {
const fragment = domFragmentMap.get(modifiedNode.serializationId);
if (fragment) {
fragment.node = modifiedNode;
}
});
});
});