Skip to content

fix: create default slot in custom elements without initial children#17705

Open
veeceey wants to merge 4 commits intosveltejs:mainfrom
veeceey:fix/issue-13638-custom-element-default-slot
Open

fix: create default slot in custom elements without initial children#17705
veeceey wants to merge 4 commits intosveltejs:mainfrom
veeceey:fix/issue-13638-custom-element-default-slot

Conversation

@veeceey
Copy link
Contributor

@veeceey veeceey commented Feb 14, 2026

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 because get_custom_elements_slots checks childNodes to 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_slots check 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.

…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-bot
Copy link

changeset-bot bot commented Feb 14, 2026

🦋 Changeset detected

Latest commit: 75dba19

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

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

@pierreeurope
Copy link

Nice fix! 👍

Just a suggestion: you might want to add a few more test scenarios to make this more comprehensive:

  1. Multiple dynamic additions: Add a second child after the first to ensure the slot continues to work correctly
  2. Empty element with fallback content: Verify that the fallback renders initially, then gets replaced when children are added
  3. Element with initial children (regression test): Ensure that custom elements with children at mount time continue to work as before

We have a test case that covers these scenarios in slot-dynamic-children if you'd like to reference it. These additional cases help ensure the fix is robust across different usage patterns.

Happy to help if you'd like to expand the test coverage!

@veeceey
Copy link
Contributor Author

veeceey commented Feb 15, 2026

Great suggestions - added tests for multiple dynamic additions, fallback content, and a regression test for elements with initial children. Also added the changeset.

veeceey and others added 2 commits February 18, 2026 21:21
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>
@svelte-docs-bot
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Svelte 5: Custom element's default <slot> not created when no initial children are passed

2 participants