Mock API requests in Storybook with Mock Service Worker.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Functions for managing the MSW worker/server instance, including access and runtime handler management. These functions provide low-level control over the MSW instance for advanced use cases.
Returns the currently active MSW worker or server instance for direct manipulation.
/**
* Get the current MSW worker/server instance
* @returns SetupWorker (browser) or SetupServer (Node.js/React Native)
* @throws Error if no worker is initialized
*/
function getWorker(): SetupWorker | SetupServer;Usage Examples:
import { initialize, getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";
// Initialize MSW first
initialize();
// Get the worker instance
const worker = getWorker();
// Add handlers at runtime
worker.use(
http.get("/api/dynamic", () => {
return HttpResponse.json({ timestamp: Date.now() });
})
);
// Reset all handlers
worker.resetHandlers();
// Listen to request events (browser only)
if ('events' in worker) {
worker.events.on('request:start', ({ request }) => {
console.log('Request started:', request.url);
});
}The returned worker instance provides access to MSW's full API:
// MSW types imported from 'msw'
import type { RequestHandler } from 'msw';
import type { SetupWorker } from 'msw/browser';
import type { SetupServer } from 'msw/node';
interface SetupWorker {
/** Add request handlers to the worker */
use(...handlers: RequestHandler[]): void;
/** Remove specific request handlers */
restoreHandlers(): void;
/** Reset all request handlers to initial state */
resetHandlers(...handlers: RequestHandler[]): void;
/** Stop the service worker */
stop(): void;
/** Event emitter for request lifecycle events */
events: {
on(event: string, listener: Function): void;
off(event: string, listener: Function): void;
};
}interface SetupServer {
/** Add request handlers to the server */
use(...handlers: RequestHandler[]): void;
/** Remove specific request handlers */
restoreHandlers(): void;
/** Reset all request handlers to initial state */
resetHandlers(...handlers: RequestHandler[]): void;
/** Stop the server */
close(): void;
/** Event emitter for request lifecycle events */
events: {
on(event: string, listener: Function): void;
off(event: string, listener: Function): void;
};
}import { getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";
const worker = getWorker();
// Add new handlers
worker.use(
http.get("/api/users/:id", ({ params }) => {
return HttpResponse.json({
id: params.id,
name: `User ${params.id}`
});
}),
http.post("/api/users", async ({ request }) => {
const userData = await request.json();
return HttpResponse.json({
id: Math.random().toString(),
...userData
});
})
);import { getWorker } from "msw-storybook-addon";
const worker = getWorker();
// Reset to initial handlers (from initialize())
worker.resetHandlers();
// Reset and add new default handlers
worker.resetHandlers(
http.get("/api/default", () => {
return HttpResponse.json({ message: "Default response" });
})
);import { getWorker } from "msw-storybook-addon";
const worker = getWorker();
// Temporarily override handlers
worker.use(
http.get("/api/temp", () => {
return HttpResponse.json({ temp: true });
})
);
// Restore to previous state
worker.restoreHandlers();import { getWorker } from "msw-storybook-addon";
const worker = getWorker();
// Listen to request events
worker.events.on('request:start', ({ request }) => {
console.log('Request started:', request.method, request.url);
});
worker.events.on('request:match', ({ request, handler }) => {
console.log('Request matched:', request.url, 'by', handler.info.header);
});
worker.events.on('request:unhandled', ({ request }) => {
console.log('Unhandled request:', request.method, request.url);
});import { getWorker } from "msw-storybook-addon";
const worker = getWorker();
const requestHandler = ({ request }) => {
console.log('Request:', request.url);
};
// Add listener
worker.events.on('request:start', requestHandler);
// Remove listener
worker.events.off('request:start', requestHandler);If getWorker() is called before initialize():
try {
const worker = getWorker();
} catch (error) {
console.error(error.message);
// "[MSW] Failed to retrieve the worker: no active worker found. Did you forget to call "initialize"?"
}import { getWorker } from "msw-storybook-addon";
const worker = getWorker();
// Check platform-specific features
if ('start' in worker) {
// Browser worker - has start() method
console.log('Running in browser');
} else if ('listen' in worker) {
// Node.js/React Native server - has listen() method
console.log('Running in Node.js/React Native');
}import { initialize, getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";
// Initialize with base handlers
initialize({}, [
http.get("/api/config", () => {
return HttpResponse.json({ env: "test" });
})
]);
// Add environment-specific handlers
const worker = getWorker();
if (process.env.NODE_ENV === 'development') {
worker.use(
http.get("/api/debug", () => {
return HttpResponse.json({ debug: true });
})
);
}import { getWorker } from "msw-storybook-addon";
import { http, HttpResponse } from "msw";
const worker = getWorker();
// Base handlers
const baseHandlers = [
http.get("/api/status", () => {
return HttpResponse.json({ status: "ok" });
})
];
// Feature-specific handlers
const userHandlers = [
http.get("/api/users", () => {
return HttpResponse.json([]);
})
];
// Apply composed handlers
worker.use(...baseHandlers, ...userHandlers);