### Start Development Server and Watch Mode
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/CONTRIBUTING.md
Builds the msw-addon in watch mode and runs Storybook for examples. This is the primary command for active development.
```bash
$ yarn start
```
--------------------------------
### Start Storybook Only
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/CONTRIBUTING.md
Starts the Storybook instance for examples and documentation without building the addon in watch mode. Alternatively, you can run `yarn storybook` within the `packages/docs` directory.
```bash
$ yarn storybook
```
--------------------------------
### Install MSW and Addon (npm)
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Install the MSW library and the Storybook addon using npm. These are development dependencies.
```sh
npm i msw msw-storybook-addon -D
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/CONTRIBUTING.md
Run this command in the root folder to install all project dependencies using Yarn Workspaces.
```bash
$ yarn
```
--------------------------------
### Install MSW and Addon, Generate Service Worker
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Install the necessary packages and generate the MSW service worker file. Ensure the service worker is placed in the public folder.
```sh
# Install both packages as dev dependencies
npm i msw msw-storybook-addon -D
# Generate the MSW service worker into the public folder
npx msw init public/
```
--------------------------------
### Define Basic Request Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Use the `msw` parameter in your story to define request handlers. This example shows how to mock a GET request to '/user' and return a JSON response.
```javascript
import { rest } from 'msw'
export const SuccessBehavior = () =>
SuccessBehavior.parameters = {
msw: {
handlers: [
rest.get('/user', (req, res, ctx) => {
return res(
ctx.json({
firstName: 'Neil',
lastName: 'Maverick',
})
)
}),
]
},
}
```
--------------------------------
### Install MSW and Storybook Addon
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Install the necessary packages for Mock Service Worker and the Storybook addon using npm or yarn.
```sh
npm i msw msw-storybook-addon -D
```
```sh
yarn add msw msw-storybook-addon -D
```
--------------------------------
### Install MSW and Addon (yarn)
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Install the MSW library and the Storybook addon using yarn. These are development dependencies.
```sh
yarn add msw msw-storybook-addon -D
```
--------------------------------
### initialize(options?, initialHandlers?)
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Starts the MSW Service Worker or Node.js intercept server. This function must be called once in `.storybook/preview.ts` before any story renders. It accepts optional configuration options and initial request handlers.
```APIDOC
## initialize(options?, initialHandlers?)
### Description
Starts the MSW Service Worker in the browser (via `setupWorker`) or a Node.js intercept server (via `setupServer`) depending on the execution environment. Must be called once in `.storybook/preview.ts` before any story renders. Returns the underlying `SetupWorker` / `SetupServer` instance.
- `options` — passed directly to `worker.start()` or `server.listen()` (e.g. `onUnhandledRequest`)
- `initialHandlers` — an optional `RequestHandler[]` spread into `setupWorker()` / `setupServer()` at creation time; useful for handlers that should apply to every story and cannot rely on Storybook's parameter-merge logic
### Request Example
```typescript
// .storybook/preview.ts
import { http, HttpResponse } from 'msw'
import { initialize, mswLoader } from 'msw-storybook-addon'
// Minimal setup — warn on any unhandled request that looks like an API call
initialize({
onUnhandledRequest: ({ url, method }) => {
const pathname = new URL(url).pathname
if (pathname.startsWith('/api/')) {
console.error(`Unhandled ${method} request to ${url}.`)
}
},
})
// OR: bypass unhandled requests silently
// initialize({ onUnhandledRequest: 'bypass' })
// OR: pass global handlers that are always active, regardless of story parameters
initialize({}, [
http.get('/api/config', () =>
HttpResponse.json({ featureFlags: { darkMode: true } })
),
])
const preview = {
loaders: [mswLoader],
}
export default preview
```
```
--------------------------------
### Define Request Handlers for a Story
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Pass request handlers to the 'msw' parameter within a story's configuration. This example mocks a GET request to '/user'.
```ts
import { http, HttpResponse } from 'msw'
export const SuccessBehavior = {
parameters: {
msw: {
handlers: [
http.get('/user', () => {
return HttpResponse.json({
firstName: 'Neil',
lastName: 'Maverick',
})
}),
],
},
},
}
```
--------------------------------
### Global MSW Setup with Named Handler Groups
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Initialize MSW and define global handlers in `.storybook/preview.ts` using named groups. These groups can be inherited or overridden by individual stories.
```typescript
// .storybook/preview.ts
import { http, HttpResponse } from 'msw'
import { initialize, mswLoader } from 'msw-storybook-addon'
initialize()
export default {
loaders: [mswLoader],
parameters: {
msw: {
handlers: {
// "auth" group applied globally to every story
auth: [
http.get('/api/login', () => HttpResponse.json({ success: true })),
http.get('/api/logout', () => HttpResponse.json({ success: true })),
],
},
},
},
}
```
--------------------------------
### Get MSW Worker Instance
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Retrieve the active MSW SetupWorker or SetupServer instance. Throws if initialize has not been called. Useful for imperative handler manipulation.
```typescript
import { getWorker } from 'msw-storybook-addon'
import { http, HttpResponse } from 'msw'
// In a Storybook global decorator, play function, or test helper:
const worker = getWorker()
// Temporarily add a one-time handler on top of the current ones
worker.use(
http.post('/api/upload', () =>
HttpResponse.json({ id: 'file_001', url: '/uploads/file_001.png' })
)
)
// Reset all runtime handlers back to the initial ones
worker.resetHandlers()
```
--------------------------------
### Initialize MSW with Custom Unhandled Request Handling
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Initialize the MSW Service Worker in `.storybook/preview.ts`. This example shows how to log unhandled requests that match a specific API path.
```ts
// .storybook/preview.ts
import { http, HttpResponse } from 'msw'
import { initialize, mswLoader } from 'msw-storybook-addon'
// Minimal setup — warn on any unhandled request that looks like an API call
initialize({
onUnhandledRequest: ({ url, method }) => {
const pathname = new URL(url).pathname
if (pathname.startsWith('/api/')) {
console.error(`Unhandled ${method} request to ${url}.`)
}
},
})
// OR: bypass unhandled requests silently
// initialize({ onUnhandledRequest: 'bypass' })
// OR: pass global handlers that are always active, regardless of story parameters
initialize({}, [
http.get('/api/config', () =>
HttpResponse.json({ featureFlags: { darkMode: true } })
),
])
const preview = {
loaders: [mswLoader],
}
export default preview
```
--------------------------------
### GraphQL Mocking with `graphql.query`
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Mock GraphQL queries using MSW's `graphql` namespace. This example shows how to intercept a specific query ('AllFilmsQuery') and return mocked JSON data for success and error scenarios.
```typescript
// FilmList.stories.ts
import { graphql, HttpResponse, delay } from 'msw'
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'
import FilmList from './FilmList'
const mockedClient = new ApolloClient({
uri: 'https://swapi-graphql.netlify.app/.netlify/functions/index',
cache: new InMemoryCache(),
defaultOptions: { watchQuery: { fetchPolicy: 'no-cache' } },
})
const withApollo = (Story) => (
)
export default { title: 'FilmList', component: FilmList, decorators: [withApollo] }
const films = [
{ title: 'A New Hope', episode_id: 4 },
{ title: 'Empire Strikes Back', episode_id: 5 },
{ title: 'Return of the Jedi', episode_id: 6 },
]
export const MockedSuccess = {
parameters: {
msw: {
handlers: [
graphql.query('AllFilmsQuery', () =>
HttpResponse.json({ data: { allFilms: { films } } })
),
],
},
},
}
export const MockedError = {
parameters: {
msw: {
handlers: [
graphql.query('AllFilmsQuery', async () => {
await delay(300)
return HttpResponse.json({ errors: [{ message: 'Access denied' }] })
}),
],
},
},
}
```
--------------------------------
### Overwrite Global Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
To override global handlers for a specific story, redefine them under the same key. This example overwrites the global `/login` handler to return a 403 status.
```typescript
import { http, HttpResponse } from 'msw'
// This story will overwrite the auth handlers from preview.ts
export const FailureBehavior = {
parameters: {
msw: {
handlers: {
auth: http.get('/login', () => {
return HttpResponse.json(null, { status: 403 })
}),
},
},
},
}
```
--------------------------------
### Add Story-Specific Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Define handlers for individual stories. Storybook merges these with global handlers. This example adds a `/profile` handler alongside the global `auth` handlers.
```typescript
import { http, HttpResponse } from 'msw'
// This story will include the auth handlers from .storybook/preview.ts and profile handlers
export const SuccessBehavior = {
parameters: {
msw: {
handlers: {
profile: http.get('/profile', () => {
return HttpResponse.json({
firstName: 'Neil',
lastName: 'Maverick',
})
}),
},
},
},
}
```
--------------------------------
### Disable Global Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
To disable global handlers for a story, set their value to `null`. This example disables the `auth` handlers while enabling other handlers like `/numbers` and `/strings`.
```typescript
import { http, HttpResponse } from 'msw'
// This story will disable the auth handlers from preview.ts
export const NoAuthBehavior = {
parameters: {
msw: {
handlers: {
auth: null,
others: [
http.get('/numbers', () => {
return HttpResponse.json([1, 2, 3])
}),
http.get('/strings', () => {
return HttpResponse.json(['a', 'b', 'c'])
}),
],
},
},
},
}
```
--------------------------------
### Configure MSW Addon in Storybook
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Initialize MSW and add the mswLoader to Storybook's preview configuration. Ensure MSW is initialized before other Storybook configurations.
```ts
import { initialize, mswLoader } from 'msw-storybook-addon'
// Initialize MSW
initialize()
const preview = {
parameters: {
// your other code...
},
// Provide the MSW addon loader globally
loaders: [mswLoader],
}
export default preview
```
--------------------------------
### Compose Global and Story Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Demonstrates how to define global MSW handlers in `preview.js` and merge them with story-specific handlers. This allows for reusable mocks like authentication endpoints.
```javascript
//preview.js
// These handlers will be applied in every story
export const parameters = {
msw: {
handlers: {
auth: [
rest.get('/login', (req, res, ctx) => {
return res(
ctx.json({
success: true,
})
)
}),
rest.get('/logout', (req, res, ctx) => {
return res(
ctx.json({
success: true,
})
)
}),
],
}
}
};
// This story will include the auth handlers from preview.js and profile handlers
SuccessBehavior.parameters = {
msw: {
handlers: {
profile: rest.get('/profile', (req, res, ctx) => {
return res(
ctx.json({
firstName: 'Neil',
lastName: 'Maverick',
})
)
}),
}
}
}
```
--------------------------------
### getWorker()
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Returns the active MSW SetupWorker (browser) or SetupServer (Node) instance. Throws an error if initialize has not been called. Useful for imperative handler manipulation outside of story parameters.
```APIDOC
## `getWorker()`
Returns the active MSW `SetupWorker` (browser) or `SetupServer` (Node) instance created by `initialize`. Throws if `initialize` has not been called. Useful for imperative handler manipulation outside of story parameters.
```ts
import { getWorker } from 'msw-storybook-addon'
import { http, HttpResponse } from 'msw'
// In a Storybook global decorator, play function, or test helper:
const worker = getWorker()
// Temporarily add a one-time handler on top of the current ones
worker.use(
http.post('/api/upload', () =>
HttpResponse.json({ id: 'file_001', url: '/uploads/file_001.png' })
)
)
// Reset all runtime handlers back to the initial ones
worker.resetHandlers()
```
```
--------------------------------
### Configure Storybook Static Directories
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Configure Storybook's `staticDirs` in `.storybook/main.ts` to serve the generated service worker file.
```ts
// .storybook/main.ts
const config = {
staticDirs: ['../public'],
// ... rest of your config
}
export default config
```
--------------------------------
### Initialize MSW with Bypass Unhandled Requests
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Configure the addon to bypass any unhandled requests, preventing MSW from logging warnings for them. This is useful when you don't need to mock every single request.
```javascript
// preview.js
import { initialize } from 'msw-storybook-addon';
initialize({
onUnhandledRequest: 'bypass'
})
```
--------------------------------
### Configure MSW Addon in Storybook
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Initialize MSW and add the mswLoader to your Storybook's preview configuration. This enables the MSW addon to function within Storybook.
```javascript
import { initialize, mswLoader } from 'msw-storybook-addon';
// Initialize MSW
initialize();
const preview = {
parameters: {
// your other code...
},
// Provide the MSW addon loader globally
loaders: [mswLoader],
}
export default preview
```
--------------------------------
### Initialize MSW with Initial Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Pass initial request handlers directly to the `initialize` function to overcome limitations with Storybook's handler composition. This ensures handlers are correctly applied when story parameters are objects.
```typescript
import { http, HttpResponse } from 'msw'
import { initialize } from 'msw-storybook-addon'
initialize({}, [
http.get('/numbers', () => {
return HttpResponse.json([1, 2, 3])
}),
http.get('/strings', () => {
return HttpResponse.json(['a', 'b', 'c'])
}),
])
```
--------------------------------
### Serve Public Folder in Storybook
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Configure Storybook to serve the 'public' folder as an asset. This is necessary for MSW to be available in the browser.
```sh
npm run storybook
```
--------------------------------
### Register MSW Loader and Define Global Handlers
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Register the `mswLoader` globally in `.storybook/preview.ts` and define global MSW handlers that apply to all stories.
```ts
// .storybook/preview.ts
import { initialize, mswLoader } from 'msw-storybook-addon'
initialize()
const preview = {
// Register globally — every story automatically gets MSW interception
loaders: [mswLoader],
parameters: {
// Optional: define handlers shared across all stories
msw: {
handlers: {
auth: [
http.get('/api/session', () =>
HttpResponse.json({ userId: 'u_42', role: 'admin' })
),
],
},
},
},
}
export default preview
```
--------------------------------
### mswLoader
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
A Storybook loader that should be registered globally in `preview.ts`. It ensures MSW is ready before each story renders and applies the appropriate request handlers based on story parameters.
```APIDOC
## mswLoader
### Description
A Storybook loader that must be registered globally in `preview.ts`. Before each story renders, it waits for MSW to be ready (`waitForMswReady`) and then calls `applyRequestHandlers` with the story's `parameters.msw` value. Using a loader (rather than a decorator) guarantees MSW is fully active before the story's component mounts and makes its first network request.
### Request Example
```typescript
// .storybook/preview.ts
import { initialize, mswLoader } from 'msw-storybook-addon'
initialize()
const preview = {
// Register globally — every story automatically gets MSW interception
loaders: [mswLoader],
parameters: {
// Optional: define handlers shared across all stories
msw: {
handlers: {
auth: [
http.get('/api/session', () =>
HttpResponse.json({ userId: 'u_42', role: 'admin' })
),
],
},
},
},
}
export default preview
```
```
--------------------------------
### Per-Story HTTP Mocking with `parameters.msw.handlers`
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Attach mock handlers directly to a story using the `parameters.msw.handlers` configuration. Supports success, loading (with `delay`), and error states.
```typescript
// UserProfile.stories.ts
import { http, HttpResponse, delay } from 'msw'
import UserProfile from './UserProfile'
export default { title: 'UserProfile', component: UserProfile }
// ✅ Success state
export const Success = {
parameters: {
msw: {
handlers: [
http.get('/api/user', () =>
HttpResponse.json({ firstName: 'Neil', lastName: 'Maverick', role: 'admin' })
),
],
},
},
}
// ✅ Loading / delay state
export const Loading = {
parameters: {
msw: {
handlers: [
http.get('/api/user', async () => {
await delay('infinite') // never resolves — shows loading skeleton
return HttpResponse.json({})
}),
],
},
},
}
// ✅ Error / forbidden state
export const Forbidden = {
parameters: {
msw: {
handlers: [
http.get('/api/user', async () => {
await delay(300)
return new HttpResponse(null, { status: 403 })
}),
],
},
},
}
```
--------------------------------
### Replace mswDecorator with mswLoader
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/MIGRATION.md
Update your Storybook configuration to use `mswLoader` instead of `mswDecorator` for better service worker registration timing. Loaders execute before stories render, ensuring the service worker is ready.
```diff
// .storybook/preview.js
-import { initialize, mswDecorator } from 'msw-storybook-addon'
+import { initialize, mswLoader } from 'msw-storybook-addon'
initialize()
const preview = {
- decorators: [mswDecorator]
+ loaders: [mswLoader]
}
```
--------------------------------
### Build Addon in Watch Mode Only
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/CONTRIBUTING.md
Builds the msw-addon in watch mode. This command is useful if you only need to focus on addon development without running Storybook. Alternatively, you can run `yarn dev` within the `packages/msw-addon` directory.
```bash
$ yarn msw:dev
```
--------------------------------
### Serve Static Assets for MSW
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Ensure the 'public' folder, containing the service worker, is served as a static asset by Storybook. This is done by configuring the `staticDirs` field in your Storybook main config file.
```sh
npm run start-storybook
```
--------------------------------
### Initialize MSW with Custom Unhandled Request Handler
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Set up a custom handler for unhandled requests to log specific error messages to the console for certain API paths. This helps in identifying and resolving unmocked requests during development.
```javascript
// preview.js
import { initialize } from 'msw-storybook-addon';
initialize({
onUnhandledRequest: ({ method, url }) => {
if (url.pathname.startsWith('/my-specific-api-path')) {
console.error(`Unhandled ${method} request to ${url}.
This exception has been only logged in the console, however, it's strongly recommended to resolve this error as you don't want unmocked data in Storybook stories.
If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses
`)
}
},
})
```
--------------------------------
### Composing Handlers: Inheriting, Overriding, and Disabling Groups
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Demonstrates how stories can compose handlers defined in `preview.ts`. This includes adding new groups, overriding existing ones with different responses, or disabling a group entirely by setting it to `null`.
```typescript
// Dashboard.stories.ts
import { http, HttpResponse } from 'msw'
// Inherits "auth" from preview.ts + adds "dashboard" group
export const LoggedIn = {
parameters: {
msw: {
handlers: {
dashboard: http.get('/api/dashboard', () =>
HttpResponse.json({ widgets: ['chart', 'table'] })
),
},
},
},
}
// Overrides "auth" with a 403 response; still inherits nothing else
export const SessionExpired = {
parameters: {
msw: {
handlers: {
auth: http.get('/api/login', () =>
HttpResponse.json(null, { status: 403 })
),
},
},
},
}
// Disables "auth" entirely for this story
export const PublicPage = {
parameters: {
msw: {
handlers: {
auth: null,
public: http.get('/api/public', () =>
HttpResponse.json({ message: 'Welcome' })
),
},
},
},
}
```
--------------------------------
### Define Global MSW Handlers in preview.ts
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Set global MSW handlers in `.storybook/preview.ts` to be applied across all stories. These handlers can be grouped under a specific key (e.g., `auth`) for better organization.
```typescript
import { http, HttpResponse } from 'msw'
// These handlers will be applied in every story
export const parameters = {
msw: {
handlers: {
auth: [
http.get('/login', () => {
return HttpResponse.json({
success: true,
})
}),
http.get('/logout', () => {
return HttpResponse.json({
success: true,
})
}),
],
},
},
}
```
--------------------------------
### Apply Request Handlers for Portable Stories (Storybook < 8.2)
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Manually apply MSW handlers declared in story parameters before rendering. This is necessary for older Storybook versions (< 8.2) in test files.
```typescript
// vitest / jest test file (Storybook < 8.2 workflow)
import { render, screen } from '@testing-library/react'
import { composeStories } from '@storybook/react'
import { applyRequestHandlers } from 'msw-storybook-addon'
import * as stories from './UserProfile.stories'
const { Success, Forbidden } = composeStories(stories)
test('renders user name on success', async () => {
// Must be called before render so MSW intercepts the request
await applyRequestHandlers(Success.parameters.msw)
render()
expect(await screen.findByText('Neil Maverick')).toBeInTheDocument()
})
test('shows error banner on 403', async () => {
await applyRequestHandlers(Forbidden.parameters.msw)
render()
expect(await screen.findByRole('alert')).toHaveTextContent(/forbidden/i)
})
```
--------------------------------
### Request Handlers Applied Automatically (Storybook ≥ 8.2)
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
In newer Storybook versions (≥ 8.2), request handlers are automatically applied via the `play` function, simplifying the testing workflow.
```typescript
// Storybook ≥ 8.2 — loaders applied automatically via play()
import { composeStories } from '@storybook/react'
import * as stories from './UserProfile.stories'
const { Success } = composeStories(stories)
test('renders user name on success', async () => {
// play() triggers mswLoader which calls applyRequestHandlers internally
await Success.play()
expect(await screen.findByText('Neil Maverick')).toBeInTheDocument()
})
```
--------------------------------
### Apply MSW Loaders Manually with Portable Stories (Storybook < 8.2)
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
For Storybook versions prior to 8.2, manually apply MSW loaders using the `applyRequestHandlers` helper before rendering your story. This is a temporary solution until upgrading to Storybook 8.
```typescript
import { applyRequestHandlers } from 'msw-storybook-addon'
import { composeStories } from '@storybook/react'
import * as stories from './MyComponent.stories'
const { Success } = composeStories(stories)
test('', async() => {
// 👇 Crucial step, so that the MSW loaders are applied
await applyRequestHandlers(Success.parameters.msw)
render()
})
```
--------------------------------
### Apply MSW Loaders Automatically with Portable Stories (Storybook 8.2+)
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
For Storybook 8.2 and higher, MSW loaders are applied automatically when using portable stories, provided the project annotations are set up correctly via the story's `play` function.
```typescript
import { composeStories } from '@storybook/react'
import * as stories from './MyComponent.stories'
const { Success } = composeStories(stories)
test('', async() => {
// The MSW loaders are applied automatically via the play function
await Success.play()
})
```
--------------------------------
### Migrate parameters.msw to Object Notation
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/MIGRATION.md
Update the `parameters.msw` syntax from an array of handlers to an object format for better convention and future compatibility. This change supports both a simple array of handlers and a named object of handlers.
```typescript
// ❌ Instead of defining the msw parameter like so:
export const MyStory = {
parameters: {
msw: [...] // some handlers here
}
}
```
```typescript
// ✅ You should set them like so:
export const MyStory = {
parameters: {
msw: {
handlers: [...] // some handlers here
}
}
}
```
```typescript
// ✅ Or like so:
export const MyStory = {
parameters: {
msw: {
handlers: {
someHandlerName: [...] // some handlers here
}
}
}
}
```
--------------------------------
### Configure MSW to Log Unhandled Requests
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Configure MSW to log a detailed error message to the console for specific unhandled requests. This helps in identifying and resolving issues where stories make unexpected API calls.
```typescript
import { initialize } from 'msw-storybook-addon'
initialize({
onUnhandledRequest: ({ url, method }) => {
const pathname = new URL(url).pathname
if (pathname.startsWith('/my-specific-api-path')) {
console.error(`Unhandled ${method} request to ${url}.
This exception has been only logged in the console, however, it's strongly recommended to resolve this error as you don't want unmocked data in Storybook stories.
If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses
`)
}
},
})
```
--------------------------------
### Configure MSW to Bypass Unhandled Requests
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/README.md
Use this configuration to prevent MSW from logging warnings for requests that do not have a corresponding handler. This is useful when you want MSW to simply ignore unmocked requests.
```typescript
import { initialize } from 'msw-storybook-addon'
initialize({
onUnhandledRequest: 'bypass',
})
```
--------------------------------
### applyRequestHandlers(mswParameter)
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
A low-level helper that resets the active MSW worker/server and applies the handlers declared in a story's parameters.msw. In Storybook ≥ 8.2 this is called automatically by the play function when using portable stories. In Storybook 7 / < 8.2 it must be called manually before rendering.
```APIDOC
## `applyRequestHandlers(mswParameter)` — portable stories / Storybook < 8.2
A low-level helper that resets the active MSW worker/server and applies the handlers declared in a story's `parameters.msw`. In Storybook ≥ 8.2 this is called automatically by the `play` function when using portable stories. In Storybook 7 / < 8.2 it must be called manually before rendering.
```ts
// vitest / jest test file (Storybook < 8.2 workflow)
import { render, screen } from '@testing-library/react'
import { composeStories } from '@storybook/react'
import { applyRequestHandlers } from 'msw-storybook-addon'
import * as stories from './UserProfile.stories'
const { Success, Forbidden } = composeStories(stories)
test('renders user name on success', async () => {
// Must be called before render so MSW intercepts the request
await applyRequestHandlers(Success.parameters.msw)
render()
expect(await screen.findByText('Neil Maverick')).toBeInTheDocument()
})
test('shows error banner on 403', async () => {
await applyRequestHandlers(Forbidden.parameters.msw)
render()
expect(await screen.findByRole('alert')).toHaveTextContent(/forbidden/i)
})
```
```ts
// Storybook ≥ 8.2 — loaders applied automatically via play()
import { composeStories } from '@storybook/react'
import * as stories from './UserProfile.stories'
const { Success } = composeStories(stories)
test('renders user name on success', async () => {
// play() triggers mswLoader which calls applyRequestHandlers internally
await Success.play()
expect(await screen.findByText('Neil Maverick')).toBeInTheDocument()
})
```
```
--------------------------------
### Disable Global Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Illustrates how to disable specific global MSW handlers for a particular story by setting their value to `null`. This allows you to selectively exclude certain mocks.
```javascript
// This story will disable the auth handlers from preview.js
NoAuthBehavior.parameters = {
msw: {
handlers: {
auth: null,
others: [
rest.get('/numbers', (req, res, ctx) => {
return res(ctx.json([1, 2, 3]))
}),
rest.get('/strings', (req, res, ctx) => {
return res(ctx.json(['a', 'b', 'c']))
}),
],
}
}
}
```
--------------------------------
### Generate MSW Service Worker
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Generate the service worker file for MSW. This step is crucial for enabling request interception in the browser. If you are already using MSW, you might have already completed this step.
```sh
npx msw init public/
```
--------------------------------
### Overwrite Global Handlers
Source: https://github.com/mswjs/msw-storybook-addon/blob/main/packages/docs/src/guides/GettingStarted.mdx
Shows how to override globally defined MSW handlers within a specific story. This is useful for testing different scenarios or error states for the same endpoint.
```javascript
// This story will overwrite the auth handlers from preview.js
FailureBehavior.parameters = {
msw: {
handlers: {
auth: rest.get('/login', (req, res, ctx) => {
return res(ctx.status(403))
}),
}
}
}
```
--------------------------------
### MswParameters type
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
TypeScript type for the parameters.msw field, exported via decorator.ts. Use it to type story parameter objects or custom helper functions.
```APIDOC
## `MswParameters` type
TypeScript type for the `parameters.msw` field, exported via `decorator.ts`. Use it to type story parameter objects or custom helper functions.
```ts
import type { MswParameters } from 'msw-storybook-addon'
import { http, HttpResponse } from 'msw'
// Helper that builds typed msw parameters
function successHandlers(endpoint: string, payload: unknown): MswParameters {
return {
msw: {
handlers: [
http.get(endpoint, () => HttpResponse.json(payload)),
],
},
}
}
export const Success = {
parameters: successHandlers('/api/user', { firstName: 'Neil', lastName: 'Maverick' }),
}
```
```
--------------------------------
### Typed MSW Parameters for Stories
Source: https://context7.com/mswjs/msw-storybook-addon/llms.txt
Utilize the `MswParameters` TypeScript type for defining story parameters and custom helper functions, ensuring type safety for MSW handlers.
```typescript
import type { MswParameters } from 'msw-storybook-addon'
import { http, HttpResponse } from 'msw'
// Helper that builds typed msw parameters
function successHandlers(endpoint: string, payload: unknown): MswParameters {
return {
msw: {
handlers: [
http.get(endpoint, () => HttpResponse.json(payload)),
],
},
}
}
export const Success = {
parameters: successHandlers('/api/user', { firstName: 'Neil', lastName: 'Maverick' }),
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.