CodeBlanks Logo Icon CodeBlanks

Declarative shadow DOM

HTML course · Expert · Lesson 31/39

Write SSR-friendly shadow DOM with <template shadowrootmode>.

What is declarative shadow DOM?

Imperative shadow DOM calls element.attachShadow() in JS, so server-rendered HTML has no shadow DOM and content is missing until JS loads.

Declarative shadow DOM moves this into HTML: anything inside a <template shadowrootmode="open"> becomes a shadow root at parse time. No JS is needed; it's SSR-friendly and the page ships with shadow DOM on first paint.

shadowrootmode syntax

The rule: place a <template> inside a custom element and set its shadowrootmode property to "open" or "closed". At parse time the browser turns the template into a shadow root and removes the template; the shadow root remains.

open lets outside code reach the root via element.shadowRoot; closed blocks it. Most components use open for easier testing and accessibility.

Exercise Write a profile-card with declarative shadow DOM

Write a <profile-card> element. Inside:

  • Open and close a <template shadowrootmode="open">
  • Inside the template, an <h2> with non-empty title content
  • Inside the template, a <slot name="name">
  • Outside the template but inside profile-card, an <h2 slot="name"> with non-empty name content
  • End with the </profile-card> closing tag
Show example solution
<profile-card>
  <template shadowrootmode="open">
    <h2>Profile card</h2>
    <slot name="avatar"></slot>
    <slot name="name"></slot>
    <slot name="bio"></slot>
  </template>
  <img slot="avatar" src="/user/alex/avatar.png" alt="Alex Morgan avatar">
  <h2 slot="name">Alex Morgan</h2>
  <p slot="bio">Product designer, lives in London.</p>
</profile-card>

Test yourself

  1. What's the main advantage of declarative shadow DOM over imperative attachShadow?

    <template shadowrootmode="open">...</template>
    • Less code to write
    • It works inside HTML during SSR
    • It runs faster
    • It needs no CSS encapsulation
    Show answer

    It works inside HTML during SSR — Correct. Declarative shadow DOM lives in HTML, so it's SSR-friendly and doesn't wait for JS.

  2. Complete the declarative shadow DOM template

    <template ____="open"><slot name="avatar"></slot></template>
    Show answer
    <template shadowrootmode="open"><slot name="avatar"></slot></template>
  3. Match each approach to its feature

    shadowrootmode
    In HTML
    attachShadow
    In JS
    SSR friendly
    Declarative
    Waits for JS
    Imperative

All lessons in Expert