Storybook Vue Slots Addon

9.1.5 · active · verified Sun Apr 19

The Storybook Vue Slots Addon, currently at version 9.1.5, provides robust support for integrating Vue 3 slots directly into Storybook's Component Story Format (CSF) files. This addon enables developers to define and control slot content, generate code snippets that include slot definitions, and even wrap slot content with other Vue components, enhancing the interactive documentation of complex Vue components. Maintained as a fork by Webkor, its release cadence is closely tied to major Storybook and Vue 3 versions, ensuring compatibility with the latest ecosystems. It differentiates itself by offering granular control over slot behavior through Storybook's built-in controls, making it easier to visualize and test different slot configurations without manual code changes.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates the installation, required configuration in `.storybook/main.ts` (commented), and an example CSF story file showcasing basic and advanced slot content control using `parameters.slots` and `argTypes` integration for UI control.

import type { Meta, StoryObj } from '@storybook/vue3';
import MyComponent from './MyComponent.vue';

// --- First, install the addon ---
// pnpm add -D storybook-vue-slots

// --- Then, configure in .storybook/main.ts (uncomment in your actual file) ---
// export default {
//   addons: [
//     // ... other addons
//     "storybook-vue-slots"
//   ]
// } satisfies StorybookConfig;

// --- Example MyComponent.vue ---
// <template>
//   <div style="border: 1px solid #ccc; padding: 15px; border-radius: 5px;">
//     <header><slot name="header">Default Header</slot></header>
//     <main style="margin: 10px 0;"><slot>Default Content</slot></main>
//     <footer><slot name="footer">Default Footer</slot></footer>
//   </div>
// </template>
// <script setup lang="ts"></script>

const meta: Meta<typeof MyComponent> = {
  component: MyComponent,
  title: 'Components/MyComponent with Slots',
  parameters: {
    slots: {
      // Basic string content for the default slot
      default: 'This is the default slot content set via Storybook',
      // Advanced object for a named slot with description and template
      header: {
        description: 'A slot for header content, controllable via args',
        template: `<div style="background-color: #e0f7fa; padding: 8px;">{{ args.header }}</div>`
      },
      // Another named slot demonstrating advanced options
      footer: {
        description: 'A slot for footer content, styled and controlled',
        template: `<p style="color: #616161; font-size: 0.9em;">{{ args.footer }}</p>`
      }
    }
  },
  // Define argTypes to make slot content controllable in Storybook UI
  argTypes: {
    default: { control: 'text', description: 'Content for the unnamed (default) slot' },
    header: { control: 'text', description: 'Customizable content for the header slot' },
    footer: { control: 'text', description: 'Customizable content for the footer slot' },
  }
};

export default meta;
type Story = StoryObj<typeof MyComponent>;

export const Primary: Story = {
  args: {
    default: 'Dynamic content for the default slot!',
    header: 'Dynamic Header Title',
    footer: 'Dynamic Footer Information © 2025'
  },
  // The component template needs to render the slots using args
  template: `
    <MyComponent>
      <template v-if="args.default" #default>{{ args.default }}</template>
      <template v-if="args.header" #header>{{ args.header }}</template>
      <template v-if="args.footer" #footer>{{ args.footer }}</template>
    </MyComponent>`
};

view raw JSON →