Mock Service Worker

Mock APIs in Storybook using Mock Service Worker.

View on GithubNew to Storybook?Get started

MSW Storybook Addon

Mock API requests in Storybook with Mock Service Worker.

Usage

Install

npm i msw-storybook-addon -D

Make sure you have msw@2.x installed as a peer dependency.

Generate the worker script

Next, use the MSW CLI to generate a worker script at the given path:

npx msw init ./public --save

Replace ./public with the path to your static directory of Storybook.

Configure Storybook

CSF 3.0

The loader API for CSF 3.0 is deprecated. Please consider using the CSF Next API instead.

// .storybook/main.ts
export default {
  addons: ['msw-storybook-addon'],
}
// .storybook/preview.ts
import { mswLoader } from 'msw-storybook-addon/csf3'

export default {
  loaders: [mswLoader()],
  parameters: {
    msw: [...initialHandlers]
  }
}

CSF Next

If you are using the CSF Next syntax (also known as CSF Factories), it's enough to import and call the addon function in preview.ts:

// .storybook/preview.ts
import addonMsw from 'msw-storybook-addon'

export default definePreview({
  addons: [addonMsw()],
})

parameters.msw is not supported in CSF Next. It is preserved only for CSF 3.0 to make migration easier — use the beforeEach hook instead.

Types

The addon types context.msw (and, for CSF 3.0, parameters.msw) through module augmentation. That augmentation ships with every entrypoint of the addon, so it is applied to any TypeScript program that imports the addon.

CSF Next: nothing to do. Your stories import preview, and preview imports the addon, so the types reach every story automatically.

CSF 3.0, or any setup where the stories are compiled without .storybook/preview.ts (e.g. a tsconfig.json whose include doesn't cover the .storybook directory): reference the types explicitly in your tsconfig.json:

{
  "compilerOptions": {
    "types": ["msw-storybook-addon/types"]
  }
}

In CSF 3.0, reference msw-storybook-addon/csf3 instead — it types parameters.msw as well.

Custom worker setup

By default, the addon creates and starts the worker for you: it starts quietly and ignores common asset and Storybook-internal requests. To customize that behavior (e.g. worker.start() options or initial handlers), provide a setup function that creates the worker, starts it, and returns it.

In CSF 3.0, pass it to mswLoader:

// .storybook/preview.ts
import { setupWorker } from 'msw/browser'
import { mswLoader } from 'msw-storybook-addon/csf3'

export default {
  loaders: [
    mswLoader(async () => {
      const worker = setupWorker()
      await worker.start({ onUnhandledRequest: 'bypass' })
      return worker
    })
  ]
}

In CSF Next, pass it to addonMsw:

// .storybook/preview.ts
import { setupWorker } from 'msw/browser'
import addonMsw from 'msw-storybook-addon'

export default definePreview({
  addons: [
    addonMsw(async () => {
      const worker = setupWorker()
      await worker.start({ onUnhandledRequest: 'bypass' })
      return worker
    })
  ],
})

Handlers passed to setupWorker() act as initial handlers and survive the automatic handler reset between stories.

Provide handlers

If you have correctly installed and configured this addon, it will extend your story context with the msw property. Use that reference to control API mocking in your stories, e.g. by adding request handler overrides via msw.use().

Global handlers

Provide request handlers in preview.ts to define the network behaviors that affect all your stories.

// .storybook/preview.ts
import { http, HttpResponse } from 'msw'

export default {
  beforeEach({ msw }) {
    msw.use(
      http.get('https://api.acme.com/user', () => {
        return HttpResponse.json({ name: 'John Maverick' })
      }),
    )
  },
}

Story handlers

To describe network behaviors on a story basis, add them in the beforeEach hook of the respective story.

export const UserProfileNetworkError: Story = {
  beforeEach({ msw }) {
    msw.use(
      http.get('https://api.acme.com/user', () => {
        return HttpResponse.error()
      }),
    )
  },
}

Related materials