Skip to content
← All questions
⚡ Intermediate

What are slots and what are they used for?

🧩 Components🎰 Slots

Slots let a parent component pass template content into a child. Instead of the child deciding what to render, the parent provides the markup and the child decides where to place it. This makes components flexible: a Card doesn't need a prop for every possible layout variation; it provides a slot and the parent fills it in.

Default slot

The simplest form. The child defines a <slot /> placeholder, and anything the parent puts between the component tags replaces it:

vue
<!-- Card.vue -->
<template>
  <div class="card">
    <slot />
  </div>
</template>

<!-- Usage -->
<Card>
  <p>This paragraph replaces the slot</p>
</Card>
Open in Vue Playground

If the parent provides nothing, you can set fallback content: <slot>Default text</slot>.

Named slots

When a component has multiple insertion points, give each slot a name. The parent targets them with <template #name>:

vue
<!-- PageLayout.vue -->
<template>
  <header><slot name="header" /></header>
  <main><slot /></main>
  <footer><slot name="footer" /></footer>
</template>

<!-- Usage -->
<PageLayout>
  <template #header>
    <h1>Dashboard</h1>
  </template>

  <p>Main content goes into the default slot</p>

  <template #footer>
    <span>© 2025</span>
  </template>
</PageLayout>
Open in Vue Playground

#header is shorthand for v-slot:header. Content not wrapped in a <template #name> goes into the default slot.

Scoped slots

Sometimes the child has data the parent needs to render. Scoped slots pass data from the child back to the parent through slot props:

vue
<!-- ItemList.vue -->
<script setup lang="ts">
defineProps<{ items: string[] }>()
</script>

<template>
  <ul>
    <li v-for="(item, index) in items" :key="index">
      <slot name="item" :value="item" :index="index" />
    </li>
  </ul>
</template>

<!-- Usage: parent decides how each item looks -->
<ItemList :items="['Apple', 'Banana', 'Cherry']">
  <template #item="{ value, index }">
    <strong>{{ index + 1 }}.</strong> {{ value }}
  </template>
</ItemList>
Open in Vue Playground

The child owns the data and the loop. The parent owns the rendering. This is the render delegation pattern, the same idea behind headless UI libraries like Headless UI and Radix Vue.

When to use slots vs props

Use props when the parent passes data and the child decides how to display it. Use slots when the parent decides what to display and the child decides where to place it.

ScenarioUse
Pass a title stringProp
Pass arbitrary header markupNamed slot
Child has data, parent decides renderingScoped slot
Component wraps content (card, modal, layout)Default slot

See also: How do render functions and JSX work in Vue? · What are fallthrough attributes? · What is defineExpose and when is it needed?

References

Released under the MIT License.