{"id":16448,"library":"msw-storybook-addon","title":"MSW Storybook Addon","description":"The `msw-storybook-addon` package provides a seamless integration between Storybook and Mock Service Worker (MSW), allowing developers to effectively mock API requests directly within their Storybook stories. This integration is crucial for isolated component development, enabling consistent testing environments, and showcasing various data states without requiring a live backend or complex setup. The current stable version is 2.0.7, with the project maintaining an active release cadence, frequently publishing bug fixes and minor enhancements. Its key differentiator lies in its ability to leverage MSW's powerful network interception capabilities, applying mock handlers globally across all stories or specifically overriding them on a per-story basis. This flexibility is achieved using Storybook's parameters and loaders system, facilitating robust mocking for REST, GraphQL, and other network protocols in both browser and Node.js environments. It simplifies the creation of reproducible UI states dependent on API responses.","status":"active","version":"2.0.7","language":"javascript","source_language":"en","source_url":"https://github.com/mswjs/msw-storybook-addon","tags":["javascript","storybook-addon","msw","mocking","api","graphql","network","data-state","typescript"],"install":[{"cmd":"npm install msw-storybook-addon","lang":"bash","label":"npm"},{"cmd":"yarn add msw-storybook-addon","lang":"bash","label":"yarn"},{"cmd":"pnpm add msw-storybook-addon","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required peer dependency for the core mocking functionality, as the addon leverages MSW's network interception directly.","package":"msw","optional":false}],"imports":[{"note":"Used to set up the MSW service worker globally in Storybook's `preview.ts` or `preview.js` file.","wrong":"const initialize = require('msw-storybook-addon').initialize;","symbol":"initialize","correct":"import { initialize } from 'msw-storybook-addon';"},{"note":"This is the recommended approach for applying MSW handlers to stories, replacing the deprecated `mswDecorator` since v2.0.0. It should be applied globally in `preview.ts` or per-story.","wrong":"import { mswDecorator } from 'msw-storybook-addon';","symbol":"mswLoader","correct":"import { mswLoader } from 'msw-storybook-addon';"},{"note":"Deprecated since v2.0.0 and explicitly marked `@deprecated` in v2.0.6. While it still functions, `mswLoader` is the preferred and more robust method for new projects and migrations due to better integration with Storybook's modern rendering architecture.","symbol":"mswDecorator","correct":"import { mswDecorator } from 'msw-storybook-addon';"},{"note":"TypeScript type definition for configuring MSW parameters within Storybook stories, typically used for the `msw` property in Storybook's `parameters` object.","symbol":"MswParameters","correct":"import type { MswParameters } from 'msw-storybook-addon';"}],"quickstart":{"code":"import type { Meta, StoryObj } from '@storybook/react';\nimport { http, HttpResponse } from 'msw';\nimport { initialize, mswLoader } from 'msw-storybook-addon';\nimport { within, expect } from '@storybook/test';\n\n// Assuming a simple React component that fetches user data\nconst UserProfile = () => {\n  const [user, setUser] = React.useState(null);\n  React.useEffect(() => {\n    fetch('/api/user')\n      .then(res => res.json())\n      .then(data => setUser(data));\n  }, []);\n\n  if (!user) return <div>Loading user...</div>;\n  return (\n    <div>\n      <h1>User Profile</h1>\n      <p>Name: {user.name}</p>\n      <p>Email: {user.email}</p>\n    </div>\n  );\n};\n\n// --- Configure in .storybook/preview.ts (or .js) ---\n// initialize({\n//   onUnhandledRequest: 'bypass',\n// });\n// export const loaders = [mswLoader];\n// ---------------------------------------------------\n\nconst meta: Meta<typeof UserProfile> = {\n  title: 'Components/UserProfile',\n  component: UserProfile,\n  parameters: {\n    // Default MSW handlers for all stories under this meta\n    msw: {\n      handlers: [\n        http.get('/api/user', () => {\n          return HttpResponse.json({ name: 'John Doe', email: 'john.doe@example.com' });\n        }),\n      ],\n    },\n  },\n  // Apply mswLoader globally to ensure mocks are active\n  loaders: [mswLoader]\n};\n\nexport default meta;\n\ntype Story = StoryObj<typeof UserProfile>;\n\nexport const DefaultUser: Story = {\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement);\n    await canvas.findByText('Name: John Doe');\n    await expect(canvas.findByText('Email: john.doe@example.com')).toBeInTheDocument();\n  },\n};\n\nexport const AdminUser: Story = {\n  parameters: {\n    msw: {\n      handlers: [\n        // Override specific handlers for this story\n        http.get('/api/user', () => {\n          return HttpResponse.json({ name: 'Admin User', email: 'admin@example.com', role: 'admin' });\n        }),\n      ],\n    },\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement);\n    await canvas.findByText('Name: Admin User');\n    await expect(canvas.findByText('Email: admin@example.com')).toBeInTheDocument();\n  },\n};\n","lang":"typescript","description":"This quickstart demonstrates how to set up `msw-storybook-addon` and define MSW handlers globally for a component's stories, as well as how to override handlers on a per-story basis. It also shows a basic Storybook `play` function to verify the mocked data."},"warnings":[{"fix":"Upgrade your `msw` package to `^2.0.0` and migrate your request handlers according to the MSW 1.x to 2.x migration guide (e.g., `rest` is now `http`).","message":"Version 2.0.0 of `msw-storybook-addon` introduced a breaking change requiring MSW version 2.0.0 or higher. Existing projects using MSW v1.x will need to migrate their MSW handlers to the v2.x format.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Replace `addDecorator(mswDecorator)` with `loaders: [mswLoader]` in your Storybook `preview.ts` or individual story `meta` or `StoryObj` configurations.","message":"The `mswDecorator` has been deprecated in favor of `mswLoader` since v2.0.0. While `mswDecorator` may still function, `mswLoader` offers better integration with Storybook's modern architecture and lifecycle.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Run `npx msw init <YOUR_PUBLIC_DIR>` (e.g., `npx msw init public`) to create the Service Worker file. Ensure `initialize()` is called in `.storybook/preview.ts` (or `.js`). Verify the file is accessible in your browser's developer tools.","message":"For browser environments, MSW requires a Service Worker file (`mockServiceWorker.js`) to be present and correctly registered. If mocks are not working, ensure this file is served correctly from your public directory and `initialize()` is called.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `'msw-storybook-addon'` is correctly listed in the `addons` array in your `.storybook/main.js` or `.storybook/main.ts` configuration file.","message":"Incorrectly configuring the addon in Storybook's `main.js` or `main.ts` can lead to the addon not being active or not exposing its functionalities (like the `mswLoader`).","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Update your MSW handlers to the v2.x format. For instance, `rest.get` becomes `http.get`, and handlers return `HttpResponse` instead of plain objects. Refer to the MSW migration guide.","cause":"This error typically occurs when using MSW v1.x handler syntax with an MSW v2.x setup, which `msw-storybook-addon` v2.x requires.","error":"TypeError: handler.isMiddleware is not a function"},{"fix":"Run `npx msw init <YOUR_PUBLIC_DIR>` (e.g., `npx msw init public`) to generate the service worker. Ensure it's in a path accessible by your web server/Storybook. Also, confirm `initialize({ onUnhandledRequest: 'bypass' })` is called in `.storybook/preview.ts`.","cause":"The MSW Service Worker (required for browser mocking) could not be registered, often due to the `mockServiceWorker.js` file being missing, incorrectly placed, or inaccessible.","error":"Error: [MSW] Failed to register a Service Worker. This can happen if the 'msw' package is not installed or the 'mockServiceWorker.js' file is not found."},{"fix":"Ensure `import type { MswParameters } from 'msw-storybook-addon';` is present and that your Storybook type definitions are set up to extend `Parameters` correctly, for example, by adding `msw-storybook-addon` to your `tsconfig.json`'s `types` array or by directly importing `MswParameters` where needed.","cause":"This TypeScript error indicates that Storybook's `Parameters` type is not aware of the `msw` property, typically because the addon's types haven't been merged correctly.","error":"Property 'msw' does not exist on type 'Parameters<typeof C>'"}],"ecosystem":"npm"}