Docs
Storybook Docs

Storybook for SvelteKit

Storybook for SvelteKit is a framework that makes it easy to develop and test UI components in isolation for SvelteKit applications.

Install

To install Storybook in an existing SvelteKit project, run this command in your project's root directory:

npm create storybook@latest

You can then get started writing stories, running tests and documenting your components. For more control over the installation process, refer to the installation guide.

Requirements

  • SvelteKit โ‰ฅ 3

  • Vite โ‰ฅ 8

Run Storybook

To run Storybook for a particular project, run the following:

npm run storybook

To build Storybook, run:

npm run build-storybook

You will find the output in the configured outputDir (default is storybook-static).

Configure

This section covers SvelteKit support and configuration options.

Supported features

All Svelte language features are supported out of the box, as the Storybook framework uses the Svelte compiler directly. However, SvelteKit has some Kit-specific modules that aren't supported. Here's a breakdown of what will and will not work within Storybook:

ModuleStatusNote
$app/envโœ… Supportedversion is always empty in Storybook. The deprecated $app/environment works the same way.
$app/env/public๐Ÿšง Partially supportedStatic variables are supported. Dynamic variables are always undefined, because Storybook has no server to provide them.
$app/formsโš ๏ธ ExperimentalSee How to mock.
$app/manifest๐Ÿšง Partially supportedOnly has values in development mode. In a built Storybook, every list is empty.
$app/navigationโš ๏ธ ExperimentalSee How to mock.
$app/pathsโœ… Supported
$app/stateโš ๏ธ ExperimentalSee How to mock.
$env/*/public๐Ÿšง Partially supportedDeprecated by SvelteKit. Works the same way as $app/env/public.
#libโœ… Supported
@sveltejs/kit/*โœ… Supported
$app/env/privateโ›” Not supportedThis is a server-side feature, and Storybook renders all components on the client. Storybook fails to load stories that import it. Mock the module that imports it with a mock file.
$app/serverโ›” Not supportedThis is a server-side feature, and Storybook renders all components on the client. Storybook fails to load stories that import it. Mock the module that imports it with a mock file.
$env/*/privateโ›” Not supportedDeprecated by SvelteKit. Works the same way as $app/env/private.
Remote functionsโ›” Not supportedStorybook has no server to run them on, and building Storybook fails when a story imports one.
$app/service-workerโ›” Not supportedThis is a service worker feature, which does not apply to Storybook.

Static assets

Storybook serves the files in your SvelteKit static directory at the root, like SvelteKit does. If you set files.assets to another directory in your SvelteKit config, add that directory to staticDirs so that storybook build includes it.

How to mock

To mock a SvelteKit import you can define it within parameters.sveltekit_experimental:

MyComponent.stories.svelte
This snippet doesn't exist for react.
<script module>
  import preview from '../.storybook/preview';
 
  import MyComponent from './MyComponent.svelte';
 
  const { Story } = preview.meta({
    component: MyComponent,
  });
</script>
 
<Story
  name="MyStory"
  parameters={{
    sveltekit_experimental: {
      state: {
        page: {
          data: {
            test: 'passed',
          },
        },
        navigating: {
          to: {
            route: { id: '/storybook' },
            params: {},
            url: new URL('http://localhost/storybook'),
          },
        },
        updated: {
          current: true,
        },
      },
    },
  }}
/>

The available parameters are documented in the API section, below.

The default link-handling behavior (e.g., when clicking an <a href="..." /> element) is to log an action to the Actions panel.

You can override this by assigning an object to parameters.sveltekit_experimental.hrefs, where the keys are strings representing an href, and the values define your mock. For example:

MyComponent.stories.svelte
This snippet doesn't exist for react.
<script module>
  import preview from '../.storybook/preview';
 
  import MyComponent from './MyComponent.svelte';
 
  const { Story } = preview.meta({
    component: MyComponent,
  });
</script>
 
<Story
  name="MyStory"
  parameters={{
    sveltekit_experimental: {
      hrefs: {
        '/basic-href': (to, event) => {
          console.log(to, event);
        },
        '/root.*': {
          callback: (to, event) => {
            console.log(to, event);
          },
          asRegex: true,
        },
      },
    },
  }}
/>

See the API reference for more information.

Writing native Svelte stories

The Svelte frameworks ship with built-in support for writing stories for your Svelte components using the template syntax, via Svelte CSF.

FAQ

How do I manually install the SvelteKit framework?

First, install the framework:

npm install --save-dev @storybook/sveltekit

Then, update your .storybook/main.js|ts to change the framework property:

.storybook/main.js
This snippet doesn't exist for react.
export default {
  // ...
  framework: '@storybook/sveltekit', // ๐Ÿ‘ˆ Add this
  // svelteOptions: { ... }, ๐Ÿ‘ˆ Remove this
};

Finally, these packages are now either obsolete or part of @storybook/sveltekit, so you no longer need to depend on them directly. You can remove them (npm uninstall, yarn remove, pnpm remove) from your project:

  • @storybook/svelte-vite
  • storybook-builder-vite
  • @storybook/builder-vite

API

Parameters

This framework contributes the following parameters to Storybook, under the sveltekit_experimental namespace:

forms

Type: { enhance: () => void }

Provides mocks for the $app/forms module.

forms.enhance

Type: () => void

A callback that will be called when a form with use:enhance is submitted.

hrefs

Type: Record<[path: string], (to: string, event: MouseEvent) => void | { callback: (to: string, event: MouseEvent) => void, asRegex?: boolean }>

If you have an <a /> tag inside your code with the href attribute that matches one or more of the links defined (treated as regex based if the asRegex property is true) the corresponding callback will be called. If no matching hrefs are defined, an action will be logged to the Actions panel. See Mocking links for an example.

Type: See SvelteKit docs

Provides mocks for the $app/navigation module.

Type: See SvelteKit docs

A callback that will be called whenever goto is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

A callback that will be called whenever pushState is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

A callback that will be called whenever replaceState is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

A callback that will be called whenever invalidate is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

A callback that will be called whenever invalidateAll is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

A callback that will be called whenever refreshAll is called. If no function is provided, an action will be logged to the Actions panel.

Type: See SvelteKit docs

An object that will be passed to the afterNavigate function, which will be invoked when the onMount event fires. Storybook merges it into a navigation with type: 'enter' and shallow: false, so the callback always gets a full navigation object.

state

Type: See SvelteKit docs

Provides mocks for the $app/state module.

state.navigating

Type: See SvelteKit docs

A partial version of the navigating store.

state.page

Type: See SvelteKit docs

A partial version of the page store.

state.updated

Type: { current: boolean }

An object representing the current value of updated. You can also access updated.check(), which will be a no-op.

Options

You can pass an options object for additional configuration if needed:

.storybook/main.js
This snippet doesn't exist for react.
export default {
  // ...
  framework: {
    name: '@storybook/sveltekit',
    options: {
      // ...
    },
  },
};

The available options are:

builder

Type: Record<string, any>

Configure options for the framework's builder. For Sveltekit, available options can be found in the Vite builder docs.

docgen

Type: boolean

Default: true

Enables or disables automatic documentation generation for component properties. When disabled, Storybook will skip the docgen processing step during build, which can improve build performance.

.storybook/main.js
This snippet doesn't exist for react.
// Replace your-framework with svelte-vite or sveltekit
export default {
  framework: {
    name: '@storybook/your-framework',
    options: {
      docgen: false, // Disable docgen for better performance
    },
  },
};

When to disable docgen

Disabling docgen can improve build performance for large projects, but argTypes won't be inferred automatically, which will prevent features like Controls and docs from working as expected. To use those features, you will need to define argTypes manually.