DEV Community

Abdullah Bashir
Abdullah Bashir

Posted on

From Svelte 4 to Svelte 5: Understanding Slots (default and named)

There are a lot of changes that might be confusing in Svelte 5, which is why I'm trying to document my learning process from Svelte 4 to Svelte 5.
One of them is using slots in Svelte 5. It was a much more straightforward process in <= Svelte 4:

Default Slots

Parent.svelte (default slots, svelte 4)

<Child>
<div>
// Your slot content
</div>
</Child>
Enter fullscreen mode Exit fullscreen mode

Child.svelte (default slot, svelte 4)

<slot />
Enter fullscreen mode Exit fullscreen mode

In Svelte 5, you need to use the @render syntax to render the slot, which you also take from the new $props():

Parent.svelte (default slots, svelte 5)

<!-- same as svelte 4 -->
<Child>
<div>
// Your slot content
</div>
</Child>
Enter fullscreen mode Exit fullscreen mode

Child.svelte (default slot, svelte 5)

<script>
// destructure children from $props()
const { children } = $props()
</script>
<!-- render default slot here (with optional chaining just in case)-->
{@render children?.()}
Enter fullscreen mode Exit fullscreen mode

Named Slots

Named slots have also changed, using both #snippet and @render syntaxes:

Parent.svelte (named slots, svelte 4)

<Child>
<div slot="mySlot">
// Your slot content
</div>
</Child>
Enter fullscreen mode Exit fullscreen mode

Child.svelte (named slot, svelte 4)

<slot name="mySlot" />
Enter fullscreen mode Exit fullscreen mode

In Svelte 5, you need to pass the slot with #snippet, then use the @render syntax to render the slot, which you also take from the new $props():

Parent.svelte (named slots, svelte 5)

<!-- same as svelte 4 -->
<Child>
{#snippet mySlot()}
<div>
// your slot content
</div>
{/snippet}
</Child>
Enter fullscreen mode Exit fullscreen mode

Child.svelte (named slot, svelte 5)

<script>
// destructure children from $props()
const { mySlot } = $props()
</script>
<!-- render default slot here-->
{@render mySlot()}
Enter fullscreen mode Exit fullscreen mode

Extras: You can also conditionally render content based on if a slot is passed with an if block:

Child.svelte (named slot, svelte 5, conditional render)

<script>
// destructure children from $props()
const { mySlot } = $props()
</script>
{#if mySlot}
<p>My Slot Section is rendered here</p>
<!-- render default slot here-->
{@render mySlot()}
{/if}
Enter fullscreen mode Exit fullscreen mode

I'll keep documenting any changes as I come across them. By the way, what do you think of Svelte 5? Is the increase in compile time, the reduction in build size (for larger projects), and the extra features worth the added complexity?

Happy Hacking!

Top comments (0)