@fusion.dev/helix-docs 0.24.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,8 +36,61 @@ Before those two guards, neither component could be server-rendered at all. Both
36
36
  looked correct in every browser, because the client always has a root and always
37
37
  has a tree.
38
38
 
39
- **Anything that inspects the tree runs in `firstUpdated` or later**, and is
40
- therefore a client-side enhancement by definition.
39
+ **Anything that inspects the tree reads it through `this.knownChildren`**, in
40
+ `willUpdate` or in a getter the render calls. It is every child on a client and
41
+ none on a server, so the server renders "not known yet" and the client's first
42
+ render already has the answer. Reading after the render instead means two
43
+ renders on every client, which Lit's dev build warns about.
44
+
45
+ Not known is not empty. `this.childrenKnown` is false on a server, and a list
46
+ there doesn't render its "Nothing to show" over items it can't see.
47
+
48
+ ## Declarative shadow DOM
49
+
50
+ If you render with Lit SSR, its declarative shadow DOM hydrates. Load Lit's
51
+ hydration support before the components:
52
+
53
+ ```ts
54
+ import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
55
+ import '@fusion.dev/helix'
56
+ ```
57
+
58
+ Hydration assumes the markup already shows the client's first render. A value
59
+ that differs is never written, so the page keeps the server's, and a template
60
+ that differs throws. So while hydrating, a component renders exactly what the
61
+ server did, and anything it could only learn in a browser waits for the update
62
+ after:
63
+
64
+ - `this.hydrating` is true for the render that hydrates.
65
+ - `this.knownChildren` is empty during it, as on the server.
66
+ - `this.finishHydration()`, called from `firstUpdated`, asks for the update that
67
+ reads what was skipped.
68
+
69
+ Two things the platform does before any script can listen, and how components
70
+ answer them:
71
+
72
+ - **A declarative shadow root reports its slots as it is parsed.** A component
73
+ never learns what's slotted from `slotchange` alone. It reads its children
74
+ first and uses `slotchange` for later changes.
75
+ - **The parser fetches images.** A `load` or `error` can fire before hydration,
76
+ so a component asks the image what happened (`this.serverRendered`) and relays
77
+ the event a task later.
78
+
79
+ A component that assigns its slots by hand gets a root that can only assign by
80
+ name, because HTML can't declare manual assignment. On such a root
81
+ (`this.assignsByName`) it writes `slot` onto its children with `this.route()`,
82
+ and only there.
83
+
84
+ A page's own scripts should run after the definitions load. That's the order
85
+ hydration expects: a property set before hydration is one the server never
86
+ rendered with.
87
+
88
+ `bun run check:spec:dsd` renders every example with Lit SSR, hydrates it in
89
+ Chromium, and compares it with the same example rendered on a client.
90
+
91
+ React server components don't use any of this. Their output is replayed through
92
+ DOM APIs, and DSD doesn't activate for nodes a script inserts. See
93
+ [React](./react).
41
94
 
42
95
  ## Never initialize state in `connectedCallback`
43
96
 
@@ -110,12 +110,12 @@ import '@fusion.dev/helix' // ❌ the barrel
110
110
 
111
111
  One family per module, so you are not shipping the library to use a button.
112
112
 
113
- ## There is no declarative shadow DOM
113
+ ## Declarative shadow DOM is opt-in
114
114
 
115
- Components render on the server through Lit SSR in our own tests, but the app
116
- ships no DSD, and the shadow styles arrive with the definition rather than in
117
- the markup. You do not need to configure anything for this; it is here so the
118
- absence is not mistaken for something missing.
115
+ The site ships no DSD, and the shadow styles arrive with the definition rather
116
+ than in the markup. You don't need to configure anything for that. If you render
117
+ with Lit SSR yourself, its declarative shadow DOM hydrates: see
118
+ [Server rendering](./server-rendering).
119
119
 
120
120
  The short version of why: DSD cannot activate for script-inserted nodes, a
121
121
  server component's output is replayed from the flight payload through DOM APIs