# XPaths in the modern age

> XPath selectors offer powerful querying capabilities but face compatibility challenges with modern web technologies like Web Components and Vue 3.

Published: Jun 1, 2023
By Nikhil Verma

> This is a mirror of the original post on [dev.to](https://dev.to/nikhilverma/xpaths-in-the-modern-age-1gah). For discussion and comments, please visit the original post.

XPaths are document query selectors for HTML and XML. They're more powerful than CSS selectors and let you express complex queries.

Let me show you an example. Say you want to find the Google Search button by starting from a search input field. With XPaths you can do:

```javascript
$x(`//textarea/ancestor::form//input[@value="Google Search"]`);
```

Try doing that with CSS selectors - you can't traverse up the DOM like that.

## Web Components and Shadow DOM

XPath is a pretty old specification (created in 1999 and last updated in 2016). It doesn't support Shadow DOM.

The specification doesn't account for Web Components which were invented way after XPath was created. This means XPath expressions cannot directly select elements within shadow DOM structures.

You have to first identify the component using XPath, then manually access its `shadowRoot` property to navigate deeper:

```javascript
const host = $x(`//my-component`)[0];
const shadowElement = host.shadowRoot.querySelector(".element");
```

For nested components, this approach becomes unwieldy.

CSS selectors have the same limitation. The Lit library addresses this through custom `@query` decorators for element discovery.

## Vue 3's Text Node Problem

Vue 3 introduced a specific problem with XPath: it appends "anchor" nodes (empty text nodes) during child slot rendering to optimize updates.

These invisible text nodes interfere with XPath's `contains(text())` functionality. When you try to select elements based on text content, the anchors break your selection logic:

```javascript
// This might not work as expected in Vue 3
$x(`//button[contains(text(), "Click me")]`);
```

## The Solution: xpath-next

I created `xpath-next`, a modified XPath polyfill that adds Shadow DOM support and Vue 3 text node compatibility. While non-standard, this approach maintains development velocity without waiting for spec alignment.

You can find it on GitHub: [xpath-next](https://github.com/nikhilverma/xpath-next)

## Key Takeaway

As web technologies evolve, previously reliable tools can become incompatible with modern frameworks. Sometimes the practical solution is implementing a custom workaround rather than waiting for ecosystem-wide changes.

**Reliable technologies stop being so because the ecosystem moves on and makes them incompatible.** Understanding these limitations helps you choose the right tool for your specific context.
