Fixed
Status Update
Comments
pa...@google.com <pa...@google.com>
pa...@google.com <pa...@google.com> #2
Hi Ed, Thank you so much for these suggestions. I've been reviewing them and merging them in. Hopefully it should be live. I've included a thank you note too in the article.
ed...@modk.it <ed...@modk.it> #3
Great! Thanks a lot, I'll look for the live updates soon!
Description
Problem
In the Component Hydration content, the following explanation about checking for
any existing shadow root in your element's constructor
is incorrect.This is only true for shadow root's with
shadowrootmode="open"
. There are actually 3 reasons the value can be null, not two as the existing contents states:If the value is null:
shadowrootmode="closed"
Similarly the example that follows is also an incorrect strategy for dealing with Shadow Roots added during SSR (or at least only useful for shadow root's with
shadowrootmode="open"
).Again, this is only useful for the limited case where
shadowrootmode="open"
. Changeshadowrootmode
to"closed"
and debug the constructor to see the current code will re-attach the shadow unnecessarily. A more general solution which covers all cases should be shown instead. There is already a code example (follows below) for a general solution that usesElementInternals.shadowRoot
instead ofthis.shadowRoot
, so introducing the above example is confusing at best.Potential Fix
To solve these issue, you will need to introduce
ElementInternals.shadowRoot
before you introduce the SSR problem and example (i.e. handling previously rendered declarative Shadow DOM). This is so that the example can useElementInternals.shadowRoot
instead ofthis.shadowRoot
which will be null if theclosed
mode is used. Here is a potential flow which mostly just re-orders the content and removes the unnecessary first code example (merging some parts with the second example).Custom Elements and detecting existing Shadow Roots
Declarative Shadow DOM can be used on its own as a way to encapsulate styles or customize child placement, but it's most powerful when used with Custom Elements. Components built using Custom Elements get automatically upgraded from static HTML. With the introduction of Declarative Shadow DOM, it's now possible for a Custom Element to have a shadow root before it gets upgraded.
Custom Elements have been around for a while, and until now there was no reason to check for an existing shadow root before creating one using
attachShadow()
. Declarative Shadow DOM includes a small change that allows existing components to work despite this: calling theattachShadow()
method on an element with an existing Declarative Shadow Root will not throw an error. Instead, the Declarative Shadow Root is emptied and returned. This allows older components not built for Declarative Shadow DOM to continue working, since declarative roots are preserved until an imperative replacement is created.For newly-created Custom Elements, a new ElementInternals.shadowRoot property provides an explicit way to get a reference to an element's existing Declarative Shadow Root, both open and closed. This can be used to check for and use any Declarative Shadow Root, while still falling back to
attachShadow()
in cases where one was not provided.Component hydration
A Custom Element being upgraded from HTML that includes a Declarative Shadow Root will already have that shadow root attached. This means the element's
ElementInternals
will have ashadowRoot
property already available when it is instantiated, without your code explicitly creating one. It's best to checkElementInternals.shadowRoot
for any existing shadow root in your element's constructor. If there is already a value, the HTML for this component includes a Declarative Shadow Root. If the value is null, there was no Declarative Shadow Root present in the HTML or the browser doesn't support Declarative Shadow DOM.