3

I see that some LWCs can wrap other components, e.g.

<lightning-layout>
    <lightning-layout-item>
        <p>Some content</p>
    </lightning-layout-item>
</lightning-layout>

I remember for AngularJS, you needed to set transclusion to true for a directive in order to achieve this, but I can't find anything in the LWC docs.

I have tried simply entering content in to my custom LWC, like so:

<c-my-modal>
    <p>Some content</p>
</c-my-modal>

but none of the content is rendered.

Is there a way this transclusion can be done?

2 Answers 2

4

This is how you do it in LWC. You can pass components into another components using <slot> tag.

Unnamed Slots

This example has an unnamed slot. An unnamed slot is a placeholder for any markup that a parent component passes into the body of c-slot-demo.

<!-- slotDemo.html -->
<template>
    <h1>Add content to slot</h1>
    <div>
        <slot></slot>
    </div>
</template>

Here’s the markup for a parent component that uses c-slot-demo.

<!-- slotWrapper.html -->
<template>
    <c-slot-demo>
        <p>content from parent</p>
    </c-slot-demo>
</template>

When c-slot-demo is rendered, the unnamed slot is replaced with the markup passed into the body of c-slot-demo. Here’s the rendered output of c-slot-wrapper.

<h1>Add content to slot</h1>
<div>
    <slot>
        <p>content from parent</p>
    </slot>
</div>

If a component has more than one unnamed slot, the markup passed into the body of the component is inserted into all the unnamed slots. This UI pattern is unusual. A component usually has zero or one unnamed slot.

Named Slots

This example component has two named slots and one unnamed slot.

<!-- namedSlots.html -->
<template>
    <p>First Name: <slot name="firstName">Default first name</slot></p>
    <p>Last Name: <slot name="lastName">Default last name</slot></p>
    <p>Description: <slot>Default description</slot></p>
</template>

Here’s the markup for a parent component that uses c-named-slots.

<!-- slotsWrapper.html -->
<template>
    <c-named-slots>
        <span slot="firstName">Willy</span>
        <span slot="lastName">Wonka</span>
        <span>Chocolatier</span>
    </c-named-slots>
</template>

The c-slots-wrapper component passes:

  • Willy into the firstName slot
  • Wonka into the lastName slot
  • Chocolatier into the unnamed slot

Here’s the rendered output.

<c-named-slots>
    <p>
        First Name:
        <slot name="firstName"><span slot="firstName">Willy</span></slot>
    </p>
    <p>
        Last Name:
        <slot name="lastName"><span slot="lastName">Wonka</span></slot>
    </p>
    <p>
        Description:
        <slot><span>Chocolatier</span></slot>
    </p>
</c-named-slots>
2
  • 2
    Please don't use just a link. A few lines of code would substantially improve the quality of this answer.
    – sfdcfox
    Commented Jul 31, 2019 at 13:14
  • @sfdcfox thank you for your input. As requested, I copied documentation into my post. Duplicating internet content FTW. Commented Jul 31, 2019 at 13:30
4

This is actually not exclusive to LWC. Its the standard of Web Components. You need to use slots to achieve that. However there are limitations to slots in LWC.

You can create c-my-modal as below:

<template>
    <h1>Add content to slot</h1>
    <div>
        <slot></slot>
    </div>
</template>

Also for passing multiple contents, you can use named slots.

More information can be found here: https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.create_components_slots

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .