Post

A web component keeps its markup and styles in a shadow root, and until recently the only way to make one was to call attachShadow() from JavaScript. You can write it in the HTML now, and delete the script that used to do it.

Before, on every page: document.querySelectorAll('template[shadowrootmode]').forEach((t) => { const mode = t.getAttribute('shadowrootmode'); t.parentNode.attachShadow({ mode }).append(t.content); t.remove(); });

After: <template shadowrootmode="open"> … </template> The parser turns it into that element’s shadow root as it reads the page. A server can send a component fully rendered, and it looks right before any script has loaded.

One thing to check first. These shadow roots are only created as the browser parses the page. Any innerHTML that inserts markup containing shadowrootmode creates none: the template stays a template. Switch those calls to setHTMLUnsafe().

0 reposts0 likes

Declarative shadow DOM finished its 30 months on August 20. Verdict: Cleared. Keep the script for components that are HTML only, with no JavaScript to render them: those break completely without it. cleared.page/2026-08/

And the fun starts when you used: :not:defined { display: none } to prevent FOUCs or any other weird reason. Because DSD - Declarative ShadowDOM creates *undefined* Custom Elements The Custom Elements JavaScript *API* makes them :defined