---
type: "Guide"
title: "Shadow DOM and SEO — web components and what crawlers see"
description: "How shadow DOM affects what search engines index: open vs closed trees, web components, and pre-rendering strategies for component-heavy sites."
resource: "https://prerender.info/guides/advanced/shadow-dom-seo"
tags: [guides, shadow dom seo, web components seo, lit element, stencil seo, closed shadow root]
timestamp: 2026-04-21T00:00:00Z
---

# Shadow DOM and SEO — web components and what crawlers see

How shadow DOM affects what search engines index: open vs closed trees, web components, and pre-rendering strategies for component-heavy sites.

## Shadow DOM

Shadow DOM is an isolated DOM tree attached to a host element, used by web components (Lit, Stencil, Polymer). Open shadow trees are traversable from outside; closed shadow trees are not. Googlebot renders open shadow trees as if they were regular DOM; closed trees are not guaranteed to be indexed.

Web components are increasingly common, especially in design systems that span multiple frontend frameworks. The SEO gotchas come from shadow DOM: crawlers handle the common case well but can miss content in closed shadow roots or in slot projections that are not hydrated.

The four steps below make shadow DOM content reliably indexable.

## Steps

1. **Use open shadow roots (attachShadow({ mode: "open" }))** — Open shadow roots are traversable from the document context. Googlebot and pre-rendering pipelines can walk them and extract content. Closed shadow roots (mode: "closed") are opaque and risk silent indexing failures.
2. **Project content through <slot> with accessible defaults** — Content passed via <slot> is visible to crawlers. Provide sensible fallback content inside the slot so the component still has indexable text even if the parent forgets to project.
3. **Include critical SEO content outside the shadow root when possible** — H1 headings, primary body copy, and key structured data should live in the light DOM (regular children) rather than inside a shadow root. This maximizes crawler coverage across engines.
4. **Pre-render the composed tree to flatten shadow boundaries** — Pre-rendering captures the rendered HTML after shadow composition. The captured snapshot is regular flat HTML — no shadow boundaries — which removes all indexing uncertainty in a single step.
### Example — Lit component with open shadow root and slot fallback

```typescript
import { html, LitElement } from "lit";
import { customElement } from "lit/decorators.js";

@customElement("product-card")
export class ProductCard extends LitElement {
  static shadowRootOptions = { mode: "open" as const };

  render() {
    return html`
      <article>
        <h2><slot name="title">Untitled product</slot></h2>
        <slot name="body">No description available</slot>
      </article>
    `;
  }
}
```


## FAQ

### Does Googlebot index closed shadow roots?

Officially undocumented. In practice Googlebot can reach content in closed shadow roots when its Chromium-based WRS renders them, but the reliability is lower than open shadow roots. Avoid closed roots for indexable content.

### What about Safari's reader mode or AI crawlers?

Non-Chromium readers treat shadow DOM inconsistently. AI crawlers with weaker JavaScript support may miss slot projections entirely. Pre-rendering flattens the tree and resolves this.

### Can we mix light DOM and shadow DOM on the same page?

Yes, and it is the recommended pattern. Keep primary content in light DOM; use shadow DOM for presentational components. Pre-rendering captures both without distinction.

## Related

- [Guide — hydration failures](/guides/advanced/hydration-failures-seo.md) — Component hydration is where shadow DOM issues surface.
- [Guide — headless browser overhead](/guides/advanced/headless-browser-overhead.md) — Render pool requirements for component-heavy sites.
- [Guide — JavaScript rendering cost](/guides/javascript-rendering-cost.md) — Cost at component-heavy sites.
- [Use case — SaaS](/use-cases/saas.md) — Design systems that span frameworks.
- [Compare — vs Prerender.io](/compare/vs-prerender-io.md) — How each service handles web components.
- [Technology — how pre-rendering works](/technology/index.md) — Pipeline primer.

## Source

Generated from prerender.info editorial content (single source of truth). The canonical, always-current version is the `resource` URL above. Claims reflect prerender.info / ostr.io editorial guidance and are not confirmed from third-party public documentation unless explicitly linked.
