|
| 1 | +# knighted-preview-root lifecycle |
| 2 | + |
| 3 | +This document explains why `knighted-preview-root` exists, when it is present in preview, and when it is removed. |
| 4 | + |
| 5 | +## What is it |
| 6 | + |
| 7 | +`knighted-preview-root` is a custom host element created inside the preview iframe document. |
| 8 | + |
| 9 | +It is the dedicated React mount container used by the preview runtime in React render mode. |
| 10 | + |
| 11 | +## Why it exists even with iframe isolation |
| 12 | + |
| 13 | +The iframe isolates user code from the outer develop application, but React still needs a stable mount point inside the iframe document itself. |
| 14 | + |
| 15 | +Using `knighted-preview-root` provides: |
| 16 | + |
| 17 | +- A deterministic mount target for `createRoot(...)`. |
| 18 | +- Clear ownership of framework-rendered content within the iframe body. |
| 19 | +- Predictable cleanup between render passes. |
| 20 | +- A clean separation between React mode behavior and DOM mode behavior. |
| 21 | + |
| 22 | +In short: |
| 23 | + |
| 24 | +- Iframe isolation answers where code runs. |
| 25 | +- `knighted-preview-root` answers where React owns the DOM in that isolated page. |
| 26 | + |
| 27 | +## When it is created |
| 28 | + |
| 29 | +`knighted-preview-root` is created only during a successful React-mode render pass: |
| 30 | + |
| 31 | +1. The runtime receives a render request with mode set to React. |
| 32 | +2. The entry module is imported successfully. |
| 33 | +3. `App` resolves to a callable component. |
| 34 | +4. React output is created successfully. |
| 35 | +5. A new `knighted-preview-root` element is appended to `document.body`. |
| 36 | +6. React mounts into that host via `createRoot(host)`. |
| 37 | + |
| 38 | +## When it is removed |
| 39 | + |
| 40 | +At the beginning of every render pass, the runtime removes existing preview roots and clears previous render state. |
| 41 | + |
| 42 | +That means old `knighted-preview-root` nodes are intentionally deleted before the next render attempt. |
| 43 | + |
| 44 | +If the next render attempt fails before host creation, no new `knighted-preview-root` will be visible for that pass. |
| 45 | + |
| 46 | +## React mode vs DOM mode |
| 47 | + |
| 48 | +React mode: |
| 49 | + |
| 50 | +- Creates `knighted-preview-root`. |
| 51 | +- Mounts React output into that host. |
| 52 | + |
| 53 | +DOM mode: |
| 54 | + |
| 55 | +- Does not create `knighted-preview-root`. |
| 56 | +- Appends DOM output directly to the iframe `body`. |
| 57 | + |
| 58 | +So it is expected to sometimes not see `knighted-preview-root` when: |
| 59 | + |
| 60 | +- The current render mode is DOM. |
| 61 | +- The React render failed before host creation. |
| 62 | +- You inspect after cleanup but before a successful remount. |
| 63 | + |
| 64 | +## Portals and notification behavior |
| 65 | + |
| 66 | +In React mode, a portal target such as `document.body` points to the iframe body, not the outer develop UI document. |
| 67 | + |
| 68 | +This is expected and is part of preview encapsulation. |
| 69 | + |
| 70 | +`knighted-preview-root` does not change portal target semantics; it only defines the primary React mount host. |
| 71 | + |
| 72 | +## Quick troubleshooting checklist |
| 73 | + |
| 74 | +If `knighted-preview-root` is missing when you expected it: |
| 75 | + |
| 76 | +1. Confirm render mode is React. |
| 77 | +2. Confirm the latest pass did not fail before mount. |
| 78 | +3. Confirm you are inspecting the iframe document, not the parent document. |
| 79 | +4. Confirm auto-render actually scheduled a new render pass for the tab you edited. |
0 commit comments