If you prefer watching video tutorials, you can watch me explain slots on YouTube
What is a slot?
Just like element, you can pass child element to Components
<div>
<div>Children</div>
</div>
<Component>
<div>Children</div>
</Component>
However, the child elements passed to a Component won't show up on the screen, unless explicitly specified using a <slot>
element in the Component.
The <slot>
element decides where to insert the child elements of the Component
<!-- Component.svelte -->
Some content #1
<slot />
Some content #2
<!-- What you'll see on the DOM -->
Some content #1
<div>Children</div>
Some content #2
You can use the <slot>
element multiple times, it just means you want to insert the child elements multiple times in various places
<!-- Component.svelte -->
Some content #1
<slot />
Some content #2
<slot />
<slot />
Some content #3
<slot />
Some content #4
<!-- What you'll see on the DOM -->
Some content #1
<div>Children</div>
Some content #2
<div>Children</div>
<div>Children</div>
Some content #3
<div>Children</div>
Some content #4
Named Slot
But sometimes you want to have some of the child elements inserted at 1 place, and the other in another place....
That's when you want a named slot!
<!-- Component.svelte -->
<slot name="header" />
Some Content here
<slot name="footer" />
To specify which elements go to which named slots, you use the slot="xxx"
attribute
<Component>
<div slot="header">Header</div>
<div slot="footer">Footer</div>
</Component>
<!-- What you'll see on the DOM -->
<div slot="header">Header</div>
Some Content here
<div slot="footer">Footer</div>
svelte:fragment
Unfortunately, if you want multiple elements going into the same slot, specifying the same slot attribute value to more than one elements end up with an error ⚠️😢
<Component>
<div slot="header">Header #1</div>
<div slot="header">Header #2</div>
<div slot="footer">Footer</div>
</Component>
<!-- ⚠️ Duplicate slot name "header" in <Component> -->
That's when you use a <svelte:fragment>
to group them!
<Component>
<svelte:fragment slot="header">
<div>Header #1</div>
<div>Header #2</div>
</svelte:fragment>
<div slot="footer">Footer</div>
</Component>
<!-- What you'll see on the DOM -->
<div>Header #1</div>
<div>Header #2</div>
Some Content here
<div slot="footer">Footer</div>
Slot fallback
Finally, what happens if you didn't pass elements to the Component, but the Component expects something with a slot?
Nothing happens!
<Component>
</Component>
<!-- What you'll see on the DOM -->
Of course, you can always provide a fallback content if nothing is provided 😅
<!-- Component.svelte -->
<slot>Fallback content</slot>
<!-- What you'll see on the DOM -->
Fallback content
Reference
- Svelte Tutorial: Slots https://svelte.dev/tutorial/slots
- Svelte Tutorial: Slots Fallbacks https://svelte.dev/tutorial/slot-fallbacks
- Svelte Tutorial: Named Slots https://svelte.dev/tutorial/named-slots
Top comments (2)
👍
Thanks for this writeup!