Signatur
Beschreibung
getHTML() wandelt die Kindknoten eines ShadowRoot in einen HTML-String um. Das Ergebnis entspricht zunächst dem Lesen von shadowRoot.innerHTML. Der Unterschied: getHTML() kann auch verschachtelte Shadow Roots in den String aufnehmen. Diese erscheinen dann als deklaratives Shadow DOM, also als <template shadowrootmode="open">…</template>.
Nützlich ist das vor allem für Server-Side Rendering (SSR), Snapshots, Tests und das Kopieren von Web-Components-Bäumen. Das erzeugte HTML lässt sich mit Element.setHTMLUnsafe(), Document.parseHTMLUnsafe() oder direkt vom HTML-Parser wieder einlesen. Dabei entstehen die Shadow Roots neu.
Welche Shadow Roots im Ergebnis landen, bestimmen die Optionen:
- Mit
serializableShadowRoots: truewerden alle verschachtelten Shadow Roots aufgenommen, die als serialisierbar markiert sind. Das sind Roots, die mitattachShadow({ mode, serializable: true })oder mit dem Attributshadowrootserializableerzeugt wurden. - Mit
shadowRoots: [...]gibst du gezielt einzelne Shadow Roots an, die aufgenommen werden sollen. Das gilt auch für nicht serialisierbare und fürclosed-Roots, sofern du eine Referenz darauf hast.
Der Shadow Root, auf dem du die Methode aufrufst, wird selbst nicht als <template> ausgegeben. Serialisiert werden nur seine Kindknoten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | Object | {} | Optionales Objekt, das steuert, wie verschachtelte Shadow Roots serialisiert werden. |
| $options.serializableShadowRoots | boolean | false | Bei true werden alle verschachtelten Shadow Roots aufgenommen, deren Eigenschaft serializable auf true steht. |
| $options.shadowRoots | ShadowRoot[] | [] | Liste von Shadow Roots, die in jedem Fall aufgenommen werden, unabhängig von serializable und auch im Modus closed. |
Rückgabewert
<template shadowrootmode="…">.Beispiele
Inhalt eines Shadow Root auslesen
const host = document.createElement('div');
const shadow = host.attachShadow({ mode: 'open' });
shadow.innerHTML = '<style>p { color: red; }</style><p>Hallo</p>';
// Ohne Optionen: entspricht shadow.innerHTML
console.log(shadow.getHTML());
Verschachtelte, serialisierbare Shadow Roots mit ausgeben
const outer = document.createElement('div');
const outerShadow = outer.attachShadow({ mode: 'open' });
const inner = document.createElement('span');
// serializable: true erlaubt die Serialisierung dieses Roots
const innerShadow = inner.attachShadow({ mode: 'open', serializable: true });
innerShadow.innerHTML = '<b>Innen</b>';
outerShadow.append(inner);
console.log(outerShadow.getHTML());
console.log(outerShadow.getHTML({ serializableShadowRoots: true }));
Gezielt einen geschlossenen Shadow Root einbeziehen
const wrapper = document.createElement('div');
const wrapperShadow = wrapper.attachShadow({ mode: 'open' });
const widget = document.createElement('my-widget');
// Closed-Root: nur über die gespeicherte Referenz erreichbar
const closedRoot = widget.attachShadow({ mode: 'closed' });
closedRoot.innerHTML = '<slot></slot><i>geheim</i>';
wrapperShadow.append(widget);
const html = wrapperShadow.getHTML({ shadowRoots: [closedRoot] });
console.log(html);
// Wiederherstellen, z. B. in einem anderen Container
const copy = document.createElement('div');
copy.setHTMLUnsafe(html);
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Methode ist erst seit 2024 in allen großen Browsern verfügbar. Prüfe sie bei Bedarf mit
'getHTML' in ShadowRoot.prototypeund greife sonst aufinnerHTMLzurück. - Ohne Optionen keine verschachtelten Roots: Wenn
serializableShadowRootsnicht aktiv ist undshadowRootsleer bleibt, werden verschachtelte Shadow Roots stillschweigend weggelassen. Es gibt keinen Fehler. serializablelässt sich nur beim Erzeugen festlegen, also überattachShadow()odershadowrootserializable. Nachträglich ändern kannst du den Wert nicht.- Sicherheit: Mit
shadowRootslegst du auch Inhalte vonclosed-Roots offen. Gib solche Strings nicht ungeprüft an Dritte weiter. Beim Einlesen mitsetHTMLUnsafe()wird nicht bereinigt (Sanitizing). Fremdes HTML kann so zu XSS führen. - Formularzustände und Event-Listener gehen verloren, genauso wie per JavaScript gesetzte Eigenschaften (z. B.
input.value, wenn das Attributvaluenicht gesetzt ist). Serialisiert werden nur Markup und Attribute. - Adoptierte Stylesheets (
adoptedStyleSheets) sind nicht im Ergebnis enthalten.