References

Beginner-friendly references for web development, with live, editable examples.

The HTML shadowrootclonable attribute

Attribute All modern browsers Updated
In short

The HTML shadowrootclonable attribute lets a declarative shadow root be copied along with its host. With it, cloneNode() or document.importNode() on the host copies the shadow root too. Without it, a cloned host arrives with no shadow tree at all.

Overview

The shadowrootclonable attribute lets a declarative shadow root survive cloning. It is a boolean attribute on a <template> with shadowrootmode, and it sets the created shadow root's clonable flag to true.

Cloning normally skips shadow trees. The DOM Standard copies a host's shadow root only when that root is clonable, and then it attaches a new shadow root to the copy with the same mode, focus delegation and serializable setting and clones the children into it. A host without the flag produces a copy whose shadowRoot is null.

The shadow root comes along even for a shallow cloneNode() call. The deep flag only decides whether the host's light DOM children are cloned, and the template is not one of them, because the parser turns it into the shadow root instead of inserting it.

The flag also matters when you copy <template> contents that contain declarative shadow roots, because document.importNode() keeps only the clonable ones. Support arrived in Chrome and Edge 124, Firefox 125 and Safari 17.5, according to MDN's compatibility data.

Syntax

<div>
  <template shadowrootmode="open" shadowrootclonable>
    <p>Copied along with the host</p>
  </template>
</div>

Values

Value
A boolean attribute: present or absent.

Example

Live example
<div id="a"><template shadowrootmode="open" shadowrootclonable><b>Clonable shadow content</b></template></div>
<div id="b"><template shadowrootmode="open"><b>Plain shadow content</b></template></div>
<p>Clones:</p>
<div id="copies"></div>
<p id="out"></p>
<script>
  const copyA = document.getElementById('a').cloneNode(true);
  const copyB = document.getElementById('b').cloneNode(true);
  document.getElementById('copies').append(copyA, copyB);
  document.getElementById('out').textContent =
    'Clone of #a has a shadow root: ' + (copyA.shadowRoot !== null) + ', clone of #b: ' + (copyB.shadowRoot !== null);
</script>

Best practices

  • Add shadowrootclonable to declarative components that you duplicate with cloneNode() or importNode(), such as rows built from a template.
  • Check host.shadowRoot.clonable on an open shadow root when a copy renders empty, since false means the shadow tree was never copied.
  • For shadow roots created in script, pass clonable: true to attachShadow(), because the template attribute only covers declarative roots.
  • Remember that a clone gets an independent copy of the shadow tree, so later changes to the original's shadow content do not carry over.

Frequently asked questions

What does shadowrootclonable do?
The shadowrootclonable attribute makes a declarative shadow root clonable. Cloning its host with cloneNode() or importNode() then gives the copy its own shadow root with the same content.
Why does cloneNode() lose my shadow DOM?
Shadow roots are not clonable by default, so cloneNode() copies the host without its shadow tree. Add shadowrootclonable to the declarative template, or pass clonable: true to attachShadow().
Does a shallow cloneNode() copy a clonable shadow root?
Yes, a shadow root marked with shadowrootclonable is copied whether cloneNode() gets true or false. The deep flag only decides whether the host's light DOM children are cloned.
Are declarative shadow roots clonable by default?
No, a declarative shadow root is clonable only when its template has shadowrootclonable. The HTML parser sets the clonable flag from that attribute and leaves it false otherwise.
Which browsers support shadowrootclonable?
MDN's compatibility data lists shadowrootclonable in Chrome and Edge 124, Firefox 125 and Safari 17.5.
Is a cloned shadow root connected to the original?
No, the clone from shadowrootclonable gets an independent shadow tree copied at that moment. Later changes to either tree do not affect the other.