> Markdown version of [Using Slots](https://vaadin.com/docs/v14/flow/templates/polymer-templates/tutorial-template-components-in-slot). Section index: [llms.txt](https://vaadin.com/docs/v14/flow/llms.txt)

# Using Slots in Polymer Templates

> **Note: Use Lit templates instead**
>
> Lit templates are recommended. Polymer templates are available in the next long term supported Vaadin version (LTS), but they are deprecated.

A Polymer template cannot render child templates created using the `Component` or `Element` API, because `PolymerTemplate` uses the shadow DOM that renders the **shadow tree**, instead of the element’s children that are in the light DOM.

To overcome this, you can add a `<slot>` element to mark the place where the light DOM elements should be rendered.

**Example**: `<slot>` element in a JavaScript Polymer template.

```js
import {PolymerElement,html} from '@polymer/polymer/polymer-element.js';

class ComponentContainer extends PolymerElement {
    static get template() {
        return html`
            <div>
                <slot></slot>
            </div>`;
    }

    static get is() {
        return 'component-container';
    }
}
customElements.define(ComponentContainer.is, ComponentContainer);
```

**Example**: Mapped Java template class.

```java
@Tag("component-container")
@JsModule("./com/example/component-container.js")
public class ComponentContainer extends PolymerTemplate<TemplateModel> {

    public ComponentContainer() {
        Element label = ElementFactory.createLabel("Main layout header");
        Element button = ElementFactory.createButton("Click me");

        getElement().appendChild(label, button);
    }
}
```

- Without the `<slot>` tag in the JavaScript template, the `label` and `button` would not be visible to the user, even though they can be located in the DOM.

- You can add multiple components that will display in the slot when added to a template element with an open `<slot></slot>`.

> **Note:** You can remove any element from a `<slot>`. It will work as expected and no longer display in the main element.

## <a id="using-default-content-in-the-slot-element"></a>Using Default Content in the \<slot> Element

The `<slot>` tag can contain default content that is displayed only if nothing else is set from the light DOM.

**Example**: `<slot>` element with default content in a JavaScript Polymer template.

```js
<div style="border: 1px solid black; padding: 10px; margin: 10px;">
    <slot>No components added</slot>
</div>
```

- 'No components added' displays initially, and is replaced when at least one child element is added.

## <a id="naming-slot-elements"></a>Naming \<slot> Elements

You can name `<slot>` elements using the `name` attribute to ensure that only wanted content is added to a particular slot.

**Example** Using the `name` attribute in the `<slot>` element in a JavaScript Polymer template.

```js
<h1><slot name="title"></slot></h1>

<div style="border: 1px solid black; margin: 5px;padding: 5px;">
    <slot>No content given!</slot>
</div>
```

- A `<label slot="title">Main header</label>` element, for example, will now NOT be positioned in the default "No content given!" slot, but rather in the `<h1><slot name="title">…​` slot.

## <a id="nesting-slot-elements"></a>Nesting \<slot> Elements

You can also nest named slots inside the main slot.

**Example**: Nested slot elements in a JavaScript Polymer template.

```js
<slot name="fullName">
    <slot name="firstName"></slot>, <slot name="lastName"></slot>
</slot>
```

- The slot shows data for the light DOM `<slot="firstName">` and `<slot="lastName">` elements, if no `<slot="fullName">` element is available. If you add an element to the `<slot="fullName">` slot, it overrides and replaces the `firstName and lastName` data.

## <a id="adding-multiple-slot-elements"></a>Adding Multiple \<slot> Elements

The default slot and any named slot can contain multiple elements.

**Example**: Defining multiple elements for the default slot and multiple named slots.

```java
@Tag("name-element")
@JsModule("./com/example/name-element.js")
public class NameElement extends PolymerTemplate<TemplateModel> {
    public NameElement() {
        Element firstName = ElementFactory.createSpan("Jack");
        Element middleName = ElementFactory.createSpan(" James");
        Element surName = ElementFactory.createSpan("Christobald");

        firstName.setAttribute("slot", "firstName");
        middleName.setAttribute("slot", "middleName");
        surName.setAttribute("slot", "lastName");

        getElement().appendChild(firstName, middleName, surName);
    }
}
```

### <a id="using-a-polymertemplate-as-a-parent-layout"></a>Using a PolymerTemplate as a Parent Layout

A `PolymerTemplate` can be used as a parent layout, by using the `<slot>` in the position where the child view should be displayed.

**Example**: JavaScript Polymer template showing the actual view, `MainLayout`, below a heading and menu.

```js
import {PolymerElement,html} from '@polymer/polymer/polymer-element.js';

class MainLayout extends PolymerElement {
    static get template() {
        return html`
            <h1>Site title</h1>
            <div class="menu">...</div>

            <!-- child content comes here -->
            <slot></slot>
        `;
    }

    static get is() {
        return 'main-layout'
    }
}
customElements.define(MainLayout.is, MainLayout);
```

To use this template file, you need a basic Java template class that is mapped to the JavaScript template file (using the `@JsModule` annotation) and that implements the `RouterLayout` interface.

**Example**: Mapped Java template class that imports the JavaScript template and implements `RouterLayout`.

```java
@Tag("main-layout")
@JsModule("./com/example/main-layout.js")
public class MainLayout extends PolymerTemplate<TemplateModel>
        implements RouterLayout {
}
```

- The `showRouterLayoutContent(HasElement)` method in the `RouterLayout` interface has a default implementation. This makes it unnecessary to write additional code, but you can override and re-implement it, if necessary.

You can now use `MainLayout` as a parent layout using the `@Route` or `@ParentLayout` annotations.

**Example**: Using the `layout` parameter in the `@Route` annotation to mark `MainLayout` as the parent layout.

```java
@Route(value="editor", layout=MainLayout.class)
public class Editor extends Div {
}

@ParentLayout(MainLayout.class)
public class MenuBar extends Div {
}
```

See the following resources for related information:

- [Router Layouts and Nested Router Targets](https://vaadin.com/docs/v14/flow/routing/tutorial-router-layout.md) for more about parent views.

- [Creating A Simple Component Using the PolymerTemplate API](https://vaadin.com/docs/v14/flow/templates/polymer-templates/tutorial-template-basic.md) for general information about the `PolymerTemplate` API.

`8C3B1409-4E48-4173-A064-278AC5E55CF1`
