Overview
When a in-browser component is placed inside a slot, auto-saved changes made to that components definition are not properly reflected in the preview canvas. The changes are successfully saved in the backend because they are loaded correctly when not placed inside a slot.
- Create a page with a component that includes a slot
- Add a in-browser code component inside a slot
- Add a in-browser code component outside the slot
- Make changes to the component (e.g., edit text)
- Observe that the component inside the slot hasn't been updated but the one outside has been updated.

Proposed resolution
User interface changes
| Comment | File | Size | Author |
|---|---|---|---|
| CleanShot 2025-04-19 at 11.56.16.gif | 1.21 MB | lauriii |
Issue fork experience_builder-3520052
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
lauriiiComment #4
lauriiiComment #6
wim leersWe missed this in #3500386: Code Components should render with their auto-saved state (if any) when rendered in the XB UI.
Comment #9
balintbrewsI went ahead and merged the MR — after thorough manual testing and reviewing the code. Keeping the issue open to add the necessary tests.
Comment #10
wim leersNow let's add the missing tests.
Comment #13
isholgueras commentedComment #14
wim leersTests are failing, so no, it's not that simple 😄
When previewing, there are none of those wrapping HTML comments. So all the existing test expectations are no longer met.
Did you see @larowlan's test suggestion of 2 days ago on the already-merged MR?
Comment #15
isholgueras commentedOh, I see. I've ran only the tests for
ComponentTreeHydratedTestlocally and it passed, but fails forComponentTreeHydratedWithBlockOverrideIf there are no comments, but the
ComponentTreeHydratedTesttests pass... maybe there is something wrong here. I'll check.Ok, I'll add more options to test.
Thanks!
Comment #16
isholgueras commentedI've added the
isPreview:trueoption to every single test to validate each.I couldn't see any output difference (in terms of wrapping html comments). Everything is handled by each
renderComponent$build['#xb_preview'] = $isPreview;.$isPreviewis not being used.$isPreview;is being used to generate the component URL, the CssLibrary, scopedDependencies, libraries and for the autosave.With this in mind, the component types that are being tested in the root are SDC and Block (with the OverrideTest), but no JsComponent. JsComponent are added in the slots.
Should we add test for them too in the
uuid-in-root?Comment #17
wim leersOut of scope here — that's being handled in #3499352: SDCs should only have get HTML comments injected when `renderComponent(isPreview: TRUE)`.
Out of scope here, being handled in #3492358: Provide ComponentSource-appropriate and -specific APIs to allow component instances to behave differently while being previewed.
What's missing here, and which will cause an output difference: a draft
JavaScriptComponentconfig entity existing. Specifically, given the existing tests use it: a draft of themy-ctacode component. Add something like this to\Drupal\Tests\experience_builder\Kernel\DataType\ComponentTreeHydratedTest::test():(source:
\Drupal\Tests\experience_builder\Kernel\ApiLayoutControllerPostTest::testWithDraftCodeComponent())That will cause "draft CSS+JS code component URLs" to appear in the resulting HTML.
Comment #18
isholgueras commentedPerfect, I'll work on that. Thanks!
Comment #19
wim leers#17 is not yet implemented, but this MR is sure looking great, plus I learned something new about PHP from @isholgueras! 😄
Comment #20
wim leersThat remaining piece of #17 is coming up again over at #3516705-5: Auto-saved changes to code components are not visible in preview-on-hover-component-list until published! 😄
Comment #21
isholgueras commentedI think it's ready for review.
The only difference that I've found in JavaScriptComponents is when is a draft in preview, but I've tested, in a separate tests, the 4 different options, JavascriptComponent regular, in draft, in preview and draft in preview.
I've also adapted the tests for the BlockOverride, that otherwise it fails.
Comment #22
isholgueras commentedThere is a conflict with 0.x that I need to work on.
Comment #23
isholgueras commentedMerge with
0.xis now complete and now the expected#is_previewworks well. If I set it as preview, it returns the'#is_preview' => TRUE, otherwise isFALSE.After rebasing
0.xall tests successfully failed 🤣.Now it's ready for review.
Comment #24
wim leersComment #25
isholgueras commentedComment #26
penyaskitoComment #27
wim leersComment #28
wim leersComment #30
wim leers