v148 · html / dom · developer trial
Renewed HTML insertion & streaming methods
A coherent set of new DOM methods for inserting HTML into an existing document. Adds positional methods (e.g. el.setHTMLBefore(), el.replaceWith() taking HTML strings) that replace the awkward insertAdjacentHTML API, plus streaming methods that accept ReadableStream for server-sent HTML chunks.
chrome://flags/#enable-experimental-web-platform-features. The method names and signatures may change before shipping.
at a glance
| Status in 148 | In developer trial (behind a flag) |
|---|---|
| Flag | chrome://flags/#enable-experimental-web-platform-features |
| Standards position | Firefox: No signal · Safari: No signal |
| Spec / explainer | WICG declarative-partial-updates explainer |
| Blink component | Blink>HTML |
| ChromeStatus | 5054329641893888 — Renewed HTML insertion & streaming methods |
why it exists
insertAdjacentHTML was designed in the IE era and has a string-enum position argument ("beforebegin", "afterend", etc.) that is error-prone and verbose. innerHTML replaces content but doesn't provide relative insertion. Neither accepts streams. This feature replaces both with ergonomic methods that follow the naming of the existing Element manipulation API and adds streaming variants for progressive server-rendered HTML.
positional insertion methods
These methods mirror the existing Node manipulation API but accept HTML strings instead of Node objects. Each parses the string in the context of the element's owner document.
| el.setHTMLBefore(html) | Inserts parsed HTML immediately before el in its parent. Replaces insertAdjacentHTML("beforebegin", html). |
|---|---|
| el.setHTMLAfter(html) | Inserts parsed HTML immediately after el. Replaces insertAdjacentHTML("afterend", html). |
| el.setHTMLFirst(html) | Inserts parsed HTML as the first child. Replaces insertAdjacentHTML("afterbegin", html). |
| el.setHTMLLast(html) | Inserts parsed HTML as the last child. Replaces insertAdjacentHTML("beforeend", html). |
| el.setHTMLReplacing(html) | Replaces el itself with parsed HTML nodes. Replaces outerHTML = html. |
streaming methods
Streaming variants accept a ReadableStream of HTML chunks and parse them progressively into the document, enabling low-latency rendering of server-streamed responses without JavaScript orchestration beyond kicking off the stream.
| el.streamHTMLBefore(stream) | Streams HTML before el. The return contract is unsettled in the explainer (promise vs WritableStream) — verify in your build. |
|---|---|
| el.streamHTMLAfter(stream) | Streams HTML after el. |
| el.streamHTMLFirst(stream) | Streams HTML as first children. |
| el.streamHTMLLast(stream) | Streams HTML as last children. |
| el.streamHTMLReplacing(stream) | Streams HTML to replace el itself. |
Error paths: the explainer does not yet define when or how these methods raise errors — its security-and-privacy questionnaire answers “It will.” One open question is whether positional insertion on an element with no parent should throw a hierarchy exception or fail silently the way before()/after() do. Until error behaviour is specified, verify it in the browser before shipping.
example
Perform positional HTML insertion or stream server-sent HTML chunks directly into an element:
// Old
container.insertAdjacentHTML("beforeend", "<li>New item</li>");
// New
container.setHTMLLast("<li>New item</li>");
Stream a fetch response into the page
const res = await fetch("/partial/comments");
const stream = res.body.pipeThrough(new TextDecoderStream());
// Stream comment HTML into #comments-container without JS parsing.
// Bare call: the return contract is unsettled (promise vs WritableStream) - do not
// rely on awaiting it until the API contract is established (see the syntax section).
document.getElementById("comments-container").streamHTMLLast(stream);
The full positional and streaming set
// Positional variants (string HTML)
item.setHTMLBefore('<li>before</li>');
item.setHTMLAfter('<li>after</li>');
list.setHTMLFirst('<li>first</li>');
item.setHTMLReplacing('<section>replaced</section>');
// Streaming variants accept a ReadableStream of HTML chunks. Their return contract is
// unsettled in the explainer (promise vs WritableStream), so the calls are shown bare -
// do not rely on awaiting them until the API contract is established.
item.streamHTMLBefore(beforeStream);
item.streamHTMLAfter(afterStream);
list.streamHTMLFirst(firstStream);
item.streamHTMLReplacing(replaceStream);
browser support
| Chrome | 148 — developer trial (flag required) |
|---|---|
| Edge | Tracking Chromium |
| Firefox | No signal |
| Safari | No signal |
see also
- WICG/declarative-partial-updates — spec repository
- Out of order streaming — declarative (no-JS) streaming companion
- chromestatus: Renewed HTML insertion & streaming methods
- chromestatus: API record 5054329641893888
- chromestatus: milestone=148 listing
- Chromium Issue 491743369
- GoogleChromeLabs/html-setters-polyfill
- WPT results: domparsing/tentative
- chrome-platform-showcase: demos