fix: create default slot in custom elements without initial children#17705
fix: create default slot in custom elements without initial children#17705veeceey wants to merge 4 commits intosveltejs:mainfrom
Conversation
…al children When a custom element defines a default slot but is mounted without any initial children, the slot element was not being created. This happened because get_custom_elements_slots only returns slots for which children already exist, so the default slot was skipped entirely. This meant that any children added dynamically after mount would not be rendered in the slot. The fix ensures the default slot is always created when the component declares one, regardless of whether initial children are present. Named slots continue to be created only when matching children exist. Fixes sveltejs#13638
🦋 Changeset detectedLatest commit: 75dba19 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Nice fix! 👍 Just a suggestion: you might want to add a few more test scenarios to make this more comprehensive:
We have a test case that covers these scenarios in Happy to help if you'd like to expand the test coverage! |
|
Great suggestions - added tests for multiple dynamic additions, fallback content, and a regression test for elements with initial children. Also added the changeset. |
Svelte's custom element slot mechanism always creates the default slot
(via $$slots.default = true), so the fallback function is never called.
The querySelector('p') returned null because the <p> fallback content
is never rendered in the shadow DOM.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes #13638
When a custom element with a
<slot>is mounted without any initial children, the default slot element wasn't being created. This is becauseget_custom_elements_slotscheckschildNodesto determine which slots have content -- if there are no children, it returns an empty object and the default slot gets skipped entirely.The result is that children added dynamically after mount never get rendered, since there's no
<slot>element for them to be assigned to.The fix moves the default slot creation outside of the
existing_slotscheck so it's always created when the component declares one. Named slots still only get created when matching children exist, which is the expected behavior.Before: default slot only created if the custom element already has children at mount time
After: default slot always created, so dynamically added children render correctly
Added a test that mounts a custom element without children, then appends a child and verifies it gets slotted properly.