DEV Community

Cover image for Composition in Svelte 3: slots
Oleksandr Demian
Oleksandr Demian

Posted on

17 7

Composition in Svelte 3: slots

Table Of Contents

Composition is a powerful tool that allows you to create complex application functionality by combining small and easily manageable components. To achieve composition in Svelte 3, you have to use a slot directive.

Slots

As a normal html element, a svelte 3 component can have some child content.You can pass any valid html data inside a component, and it will be rendered inside a slot directive:

Box.svelte

<style>
    .box {
        width: 250px;
        border: 1px solid #aaa;
        padding: 1em;
        margin: 1em;
        display: inline-block;
    }
</style>

<div class="box">
    <slot></slot>
</div>
Enter fullscreen mode Exit fullscreen mode
<script>
    import Box from "./Box.svelte";
</script>

<Box>
    <h1>Hello World</h1>
    <p>Some paragraf</p>
</Box>
Enter fullscreen mode Exit fullscreen mode

As the result you will have a box with a header and paragraph inside of a box.

Slot fallback

Slot allows you to define some custom content that will be shown if there is no child content:

SlotWithFallback.svelte

<slot>
    <h2>There is no child content!</h2>
</slot>
Enter fullscreen mode Exit fullscreen mode

App.svelte

<script>
    import SlotWithFallback from "./SlotWithFallback.svelte";
</script>

<!-- will render h1 and p -->
<SlotWithFallback>
    <h1>Hello World</h1>
    <p>Some paragraf</p>
</SlotWithFallback>

<!-- will render <h2>There is no child content!</h2> -->
<SlotWithFallback />
Enter fullscreen mode Exit fullscreen mode

Named slots

Sometimes you will need to target different slots inside the same component. You can do this by adding names to slots:

NamedBox.svelte

<style>
    .box {
        width: 250px;
        border: 1px solid #aaa;
        padding: 1em;
        margin: 1em;
        display: inline-block;
    }
</style>

<div class="box">
    <slot name="top"></slot>
    <hr />
    <slot name="bottom"></slot>
</div>
Enter fullscreen mode Exit fullscreen mode

App.svelte

<script>
    import NamedBox from "./NamedBox.svelte";
</script>

<!-- will render h1 in top slot and p in bottom slot -->
<NamedBox>
    <h1 slot="top">Title</h1>
    <p slot="bottom">Paragraph</p>
</NamedBox>
Enter fullscreen mode Exit fullscreen mode

Slot props

In Svelte 3 you can also reference variables of parent component. Let's create a box with a secret content that can be toggled using checkbox:

Secret.svelte

<script>
    let showSecret = false;
</script>

<label>
    <input type="checkbox" bind:checked={showSecret} />
    Show secret
</label>

<slot showSecret={showSecret}></slot>
Enter fullscreen mode Exit fullscreen mode

App.svelte

<script>
    import Secret from "./Secret.svelte";
</script>

<Secret let:showSecret={isSecretShown}>
    {#if isSecretShown}
        <p>Hello world!</p>
    {:else}
        <p>***********</p>
    {/if}
</Secret>
Enter fullscreen mode Exit fullscreen mode

In the example above we are referencing showSecret as isSecretShown (let:showSecret={isSecretShown}) and now we can use it as a variable. Personaly, I've found a bit stange the syntax, but I think you should understand it better this way: (expose)let:(property)showSecret={(as)isSecretShown}.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)