Data can be pushed from parent component to child component using properties then where are slots in LWC used?

Want to know more about properties? Check this out!

When you want to send markup (maybe some HTML code or HTML markup with predefined slds class names) from parent component to child component this is where slots in LWC are used.

So, the gist is, use properties to send data from parent to child components and use slots to send markup from parent to child component.

There are two types of slots  - Default slots  - Named slots

Default Slots

Let us look at an example!

This is how the parent component is going to look like.

<!-- app.html -->
<template>
    <c-child>
        <div>
            HEY!!!! THIS IS SALESFORCE CASTS!
        </div>
    </child>
</template>
app.html(parent component)

And here is the child component.

<!-- child.html -->
<template>
    <p>This is child component</p>
    <slot></slot>
</template>
child.html(child component)

Here, the markup between <c-child></c-child> tags which is

<div>
    HEY!!!! THIS IS SALESFORCE CASTS!
</div>
markup between <c-child></c-child>

is pushed to child component from parent component and the rendered child component is going to look like this.

<!-- child.html -->
<template>
    <p>This is child component</p>
    <div>
    	HEY!!!! THIS IS SALESFORCE CASTS!
    </div>
</template>
child.html

Let us look a slight variant now, I want to push two sections of markup from the parent component to the child component.

So, I have two <div> </div> sections in the parent component and 2 slots tags in the child component.

This is how the parent component is going to look like.

<!-- app.html -->
<template>
    <c-child>
            <div>
                Welcome!
            <div>
            <div>
                <span>
                    <p>
                        HEY!!!! THIS IS SALESFORCE CASTS!
                    </p>
                </span>
            </div>
    </child>
</template>
app.html

I have two <slots></slots> tags in child component, like this.

<!-- child.html -->
<template>
    <p>This is the child component</p>
    <slot></slot
    <slot></slot>
</template>

child.html

then, the 10 lines of HTML code will be pushed twice from parent to child component.

<!-- child.html -->
<template>
    <p>This is the child component</p>
    <!-- because of first slot tag -->
        <div>
            Welcome!
        <div>
        <div>
            <span>
                <p>
                    HEY!!!! THIS IS SALESFORCE CASTS!
                </p>
            </span>
        </div>
    
    <!-- because of second slot tag -->
        <div>
            Welcome!
        <div>
        <div>
            <span>
                <p>
                    HEY!!!! THIS IS SALESFORCE CASTS!
                </p>
            </span>
        </div>
</template>
child.html

Very often this might not be what we need. This acts as a bottle neck and that's when we might need Named Slots.

Named Slots

When we have two different pieces of markup that we wish to send to child component from the parent, we cannot achieve that using default slots.

Named slots are the ones that comes to our rescue here.

Let’s look at an example!

<!-- app.html -->
<template>
    <c-child>
        <div slot="first">
            Welcome!
        <div>
        <div slot="second">
            <span>
                <p>
                    HEY!!!! THIS IS SALESFORCE CASTS!
                </p>
            </span>
        </div>
    </child>
</template>
app.html

In the parent component I have defined one <div /> tag with slot as "first" and the second <div /> tag with slot "second".

Likewise, in the child component am defining the slots with the name first and second respectively.

<!-- child.html -->
<template>
    <p>This is child component</p>
    <slot name="first"></slot>
    <slot name="second"></slot>
</template>
child.html

When the component renders this is how it is going to render.

<!-- child.html -->
<template>
    <p>This is child component</p>
    
    <div slot="first">
            Welcome!
    <div>

    <div slot="second">
        <span>
            <p>
                HEY!!!! THIS IS SALESFORCE CASTS!
            </p>
        </span>
    </div>
</template>
child.html

This is exactly what we might be interested in.

This is what it is when it comes to slots.