Svelte Slots
A slot marks a spot inside a component where a parent can insert its own markup. Slots let a component control the outer structure while letting the parent decide what fills the inside.
Why Slots Matter
Props work well for passing simple values like text or numbers, but they struggle with passing entire chunks of markup. A slot solves this by opening a gap inside a component where any markup can drop in from outside.
Creating A Basic Slot
<!-- Card.svelte -->
<div style="border: 1px solid gray; padding: 10px;">
<slot></slot>
</div>
The slot tag marks the exact spot where inserted content appears. Anything placed inside a Card tag from the outside lands right where this slot sits.
Filling A Slot From The Parent
<!-- App.svelte -->
<script>
import Card from "./Card.svelte";
</script>
<Card>
<h4>Product Name</h4>
<p>Product description goes here.</p>
</Card>
The heading and paragraph land inside the bordered box defined by Card. The Card component never needed to know about the heading or paragraph text ahead of time.
Slot Fill Diagram
Card.svelte structure Content from App.svelte ------------------------ -------------------------- <div border> <h4>Product Name</h4> <slot></slot> <---- fills ---- <p>Description...</p> </div> Final Rendered Result: <div border> <h4>Product Name</h4> <p>Description...</p> </div>
Default Slot Content
Placing content directly inside the slot tag sets a fallback shown only when the parent leaves the slot empty.
<div style="border: 1px solid gray; padding: 10px;">
<slot>
<p>No content provided</p>
</slot>
</div>
A parent skipping any content between the Card tags sees "No content provided" instead of an empty box.
Named Slots For Multiple Sections
A component can define several slots, each with its own name, letting a parent fill different sections independently.
<!-- Layout.svelte -->
<div>
<header><slot name="header"></slot></header>
<main><slot></slot></main>
<footer><slot name="footer"></slot></footer>
</div>
<Layout>
<h2 slot="header">Site Title</h2>
<p>Main page content</p>
<p slot="footer">Contact us at hello@example.com</p>
</Layout>
Each piece of content lands inside its matching named slot, while content without a slot attribute fills the unnamed default slot in the middle.
Passing Data Back Through A Slot
A slot can share data from the child back to the content filling it, using a pattern called a slot prop. This lets the parent's inserted markup use values that only the child component knows about.
<!-- List.svelte -->
<script>
export let items;
</script>
{#each items as item, index}
<slot {item} {index}></slot>
{/each}
<List items={["Pen", "Book"]} let:item let:index>
<p>{index}: {item}</p>
</List>
The let: syntax on the List tag unlocks the values shared through the slot, letting the parent's markup display data that lives entirely inside the child component's loop.
Key Points
- A slot marks a spot for a parent to insert custom markup
- Default slot content shows only when a parent leaves the slot empty
- Named slots let a component define several separate fill spots
- Slots handle full markup, unlike props which handle simple values
