Try it free

Specify a logical ancestor for user interactions

  • Latest Dynatrace
  • How-to guide
  • Published May 18, 2026

Early Access

By default, the RUM JavaScript traverses the DOM parent hierarchy to collect inherited attributes such as data-dt-component, data-dt-features, data-dt-children-name, and masking. When UI elements are rendered outside their logical parent in the DOM—for example, modals, dropdowns, and tooltips that use portals—this traversal may miss the intended context.

Use the data-dt-ancestor attribute to override the DOM parent relationship with a logical parent. Set its value to a CSS selector that uniquely identifies the intended logical ancestor element.

Use cases

  • Modals and dialogs rendered at the document root that logically belong to a specific component
  • Dropdown menus using portals that render outside their trigger element
  • Tooltips and popovers positioned absolutely outside their logical context
  • Any UI pattern where the DOM structure differs from the logical component hierarchy

Affected attributes

data-dt-ancestor affects all inherited attributes: data-dt-component, data-dt-features, data-dt-children-name, and masking.

Examples

Modal rendered outside its logical parent
<!-- Dashboard component in DOM -->
<div id="dashboard" data-dt-component="Dashboard" data-dt-features="admin">
<button id="openModal">Open Settings</button>
</div>
<!-- Modal rendered at body level but logically belongs to Dashboard -->
<dialog data-dt-ancestor="#dashboard" data-dt-component="SettingsModal" open>
<button data-dt-component="Button">Save</button>
<!-- ui_element.components: ["Dashboard", "SettingsModal", "Button"] -->
<!-- ui_element.features: ["admin"] (inherited from logical ancestor) -->
</dialog>
Dropdown menu with React portal
function NavDropdown() {
return (
<nav data-dt-component="Nav" data-dt-features="navigation" id="main-nav">
<button>Menu</button>
{createPortal(
<ul data-dt-ancestor="#main-nav" data-dt-component="Dropdown">
<li data-dt-component="MenuItem">Profile</li>
{/* ui_element.components: ["Nav", "Dropdown", "MenuItem"] */}
{/* ui_element.features: ["navigation"] */}
</ul>,
document.body
)}
</nav>
);
}
Masking inheritance via logical ancestor
<!-- Masked section -->
<div id="sensitive-area" data-dt-mask data-dt-component="SensitiveData">
<span>Account Info</span>
</div>
<!-- Modal showing sensitive data -->
<dialog data-dt-ancestor="#sensitive-area" data-dt-component="EditModal" open>
<input type="text" value="user@example.com">
<!-- Element name is masked because logical ancestor has data-dt-mask -->
</dialog>

Behavior and limitations

  • To prevent infinite loops, data-dt-ancestor is followed only once during ancestor traversal. After following one logical ancestor redirect, subsequent data-dt-ancestor attributes are ignored and traversal continues via DOM parent relationships.
  • If the selector is invalid or matches no element, traversal stops at that point. There is no fallback to the DOM parent.
  • If the selector matches multiple elements, the first element in DOM order is used.
  • Traversal crosses open shadow DOM boundaries. Closed shadow roots block traversal.

Troubleshooting

When data-dt-ancestor selector issues occur, diagnostic fields are included in the event:

Error valueCauseOutcome
not_foundSelector doesn't match any elementTraversal stops; no further ancestors collected
invalid_selectorSelector is malformedTraversal stops; no further ancestors collected
multiple_indirectionSecond data-dt-ancestor encountered after already following oneTraversal continues via DOM parent

The diagnostic fields dt.support.ui_element.ancestor.error and dt.support.ui_element.ancestor.selector are included in the captured event for troubleshooting. For field specifications, see User interactions in the Semantic Dictionary.

Related tags
Digital Experience