Fumadocs

Story

Display components with controls.

Server Component Only

This feature requires using a Server Component under RSC environment.

Introduction

You can use Fumadocs Story to display & document components. It is a simple, docs-focused alternative of Storybook, it is mainly designed for component libraries.

When to use it over Storybook?

Fumadocs Story is not a replacement for Storybook, we still recommend Storybook for proper UI testing.

Installation

npm i @fumadocs/story

Add the Tailwind CSS preset.

Tailwind CSS
@import '@fumadocs/story/css/preset.css';

Create a Story

If you are new to the concept of Story, this is a short explanation from Storybook docs:

A story captures the rendered state of a UI component. It's an object with annotations that describe the component's behavior and appearance given a set of arguments.

Create a story factory to store your global settings:

lib/story.ts
import { createFileSystemCache, defineStoryFactory } from '@fumadocs/story';

export const { defineStory } = defineStoryFactory({
  // for Vercel, this is required: choose a directory for cache.
  cache:
    process.env.NODE_ENV === 'production'
      ? createFileSystemCache('.next/fumadocs-story')
      : undefined,

  tsc: {
    // we use tsc to generate controls from types
    // you can customise TypeScript options here
  },
});

Now create your first story:

import { defineStory } from '@/lib/story';
import { MyComponent } from './my-component';

export const story = defineStory(import.meta.url, {
  Component: MyComponent,
  args: {
    // default props (recommended)
    initial: {},
  },
});
  • The story must be exported as story, or the name option must be set to match the export name.
  • Fill the Component option with your component, the passed component must be a client component.

Now you can render the story like:

index.mdx
import { story } from '@/components/my-component.story';

## Overview

Preview for component:

<story.WithControl />

Callout

Configurations

Variants

You can provide multiple variants of the component with args:

import { defineStory } from '@/lib/story';
import { Callout } from '@/components/callout';

export const story = defineStory(import.meta.url, {
  Component: Callout,
  args: [
    {
      variant: 'Default',
      initial: {
        title: 'This is a Callout',
      },
    },
    {
      variant: 'Warning',
      initial: {
        title: 'This is a Callout',
      },
      // fixed values for props
      fixed: {
        type: 'warning',
      },
    },
  ],
});

controls

You can further customise on how the controls are generated:

import { defineStory } from '@fumadocs/story';
import { GraphView } from '@/components/graph-view';

export const story = defineStory(import.meta.url, {
  Component: GraphView,
  args: {
    // specify the control nodes
    controls: {
      node: {
        type: 'object',
        properties: [],
      },
    },

    // or customise the generated controls
    controls: {
      transform: (node) => node,
    },
  },
});

How is this guide?

Last updated on

On this page