DEV Community

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

Posted on

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}.

Top comments (0)