Loading…

Slots: create modifiable, placeholder content

Design Studio New Updated

Add slots to determine what content you can modify in the visual editor. You can create text-based slots or drop-zones for components.

 This article applies to Design Studio

We are currently piloting Design Studio, our new email design system, and making some information available to customers. If you don’t have access to Design Studio, please continue to use our other email editors.

How to create a slot

To create a slot, define the type of slot in <script> and insert <slot> tags in the <template> where you want users to insert or edit content. You can also add placeholder text to guide your team when they’re working in the visual editor.

To define a slot, export the slots variable for use in the visual editor and define your validation schema in the <script> tag.

<script>
  export const config = {
    "label": "My paragraph",
    presets: [
        {
          label: "My paragraph",
          content: `<my-paragraph></my-paragraph>`
        }
    ]
  };
  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.text(),
      marks: ['bold', 'italic', 'underline', 'strikethrough', 'link']
    },
  });
</script>
<template>
  <p>
    <slot>Add text</slot>
  </p>
</template>

In this example, we added validation for text through schema: Component.slots.text(),. You can also add validation for drop-zones for other components.

Inside the <template> tag, you’ll add <slot> tags where you want teammates to edit text or drop in components. Within the <slot> tag, you can also define placeholder, fallback text. In this example, after you drag this component into the visual editor, you’ll see “Add text” in the visual editor until you edit it.

You can also define multiple slots in a component file.

Define your slot

You can define slots in a few ways:

  • As text - Component.slots.text()
  • As a container for any other components - Component.slots.any()
  • As a container for specific components - Component.slots.children(['component-name-1', 'component-name-2'])

Add an editable text area

Use this to validate a slot as text. By default, you can edit all marks — bold, italics, underline, strikethrough, links, and color — in the visual editor. To limit them, follow the example below.

<script>
  export const config = {
    "label": "component-one",
    presets: [
        {
          label: "component-one",
          content: `<component-one></component-one>`
        }
    ]
  };
  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.text(),
      marks: ['bold', 'italic', 'underline', 'strikethrough', 'link', 'color']
    },
  });
</script>
<template>
  <p>
    <slot>Placeholder, fallback text</slot>
  </p>
</template>

Allow any component to be inserted

Use this to define that a slot can take any component; you can drag any component into the slot of the visual editor. Keep in mind, you may not be able to drag some components in if they have specific parents.

<script>
  export const config = {
    "label": "component-two",
    presets: [
        {
          label: "component-two",
          content: `<component-two></component-two>`
        }
    ]
  };
  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.any()
    },
  });
</script>
<template>
  <slot>Insert components here.</slot>
</template>

Allow only specific components to be inserted

Use this to define that a slot can only take certain components. Add a min to specify a minimum number of children required for the component. Add a max to specify a maximum number of children allowed.

<script>
    export const config = { 
      label: "component-three",
      presets: [
        {
          label: "component-three",
          content: `<component-three></component-three>`
        }
      ]
    };
  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.children(['component-name-1', 'component-name-2']).min(1).max(3)
    }
  });
</script>
<template>
  <div><slot>Drag in component-one or component-two.</slot></div>
</template>

Define placeholder, fallback content

You can define placeholder, fallback text for any custom component. Add text between the opening and closing <slot> tags. When you drag a component onto the visual editor canvas, you’ll see the placeholder content until you modify the component.

<script>
  export const config = {
    "label": "My first component",
    presets: [
        {
          label: "My first component",
          content: `<my-first-component></my-first-component>`
        }
    ]
  };
  export const slots = Component.defineSlots({
    default: {
      schema: Component.slots.text(),
      marks: ['bold', 'italic', 'underline', 'strikethrough', 'link']
    },
  });
</script>
<template>
  <p><slot>Placeholder, fallback content</slot></p>
</template>

 Fallback text renders in your source code

If a teammate forgets to change the text or add in a component to the slot, this fallback text will render when the email is sent.

For component drop-zones, you can add <x-empty-state/> to your <slot> tag to visually show a drop-zone. For instance, for a component that only accepts certain child components, you could include <div><slot>Insert paragraphs or buttons<x-empty-state/></slot></div> so your teammates know exactly what to do. Dragging in a component replaces the text and drop-zone so they won’t render in your output code.

Define multiple slots

You can also make a component that has multiple, editable areas in the visual editor. For instance, here’s a component that adds a basic format to an email (title, body, and an image) where title is a text slot and article is a component slot that takes as many paragraphs as you need — the main content of your message.

Notice in the script, we define two slots — one named title and the other named article. You’ll reference these in the slot elements of the template.

<!-- 
  Insert this component in your email with the following code:
  
  <email-body></email-body>
-->
<script>
  export const config = {
    label: "Email body",
    presets: [{
      label: "Email body",
      content: `<email-body></email-body>`
    }]
  };
  export const slots = Component.defineSlots({
    title: {
      schema: Component.slots.text()
    },
    article: Component.slots.children(['x-paragraph']),
  })
</script>
<template>
    <x-heading-1>
        <slot name="title">Greeting text</slot>
    </x-heading-1>
    <x-box>
        <slot name="article">Drag a paragraph here</slot>
    </x-box>
    <x-image width="517px" align="center" margin="20px 0px 20px 0px" src="file-name.png" alt="description-of-image" />
</template>
Copied to clipboard!
  Contents
Is this page helpful?