In the previous post we generated OpenAPI with TypeSpec and SWR hooks with Orval.
Here we’ll use Orval’s MSW (Mock Service Worker) generation to make Storybook request mocked APIs.
What is MSW?
MSW is a mocking library for web apps. It intercepts requests (via Service Worker in the browser) and returns mock responses.
Compared to alternatives:
- Simpler than replacing calls in code; no extra mock plumbing in your code.
- Simpler setup than running a separate JSON Server mock process.
MSW also works server‑side (Node.js) by intercepting the http module.
Storybook
Storybook lets you develop UI components in isolation.
With Next.js 13, MSW integration with a running app can be tricky—according to this issue, it didn’t work with either Pages or App Router:
This project develops components in Storybook, which is sufficient; below is how to use MSW from Storybook.
Add to Storybook
Use the MSW addon:
Install:
npm i msw msw-storybook-addon -D
Create the service worker
Generate the worker script under public/
:
npx msw init public/
Update .storybook/preview.ts
Add the addon and pass handlers (created below):
import { initialize, mswLoader } from "msw-storybook-addon";
import { handlers } from "../mocks/handlers";
// Initialize MSW
initialize();
const preview: Preview = {
parameters: {
msw: {
handlers
}
},
loaders: [mswLoader]
};
Generate MSW mocks with Orval
Edit orval.config.ts
Add mock: true
so Orval generates mocks along with SWR files:
module.exports = {
"user-api": {
input: {
target: "./openapi.yml",
},
output: {
mode: "split",
target: "./api/endpoints",
schemas: './api/models',
client: "swr",
mock: true,
},
hooks: {
afterAllFilesWrite: "prettier --write",
},
},
};
Generated userAPI.msw.ts
After enabling mocks, run npx orval
. You’ll get userAPI.msw.ts
with MSW handlers and mock data generation using @faker-js/faker
.
Add mocks/handlers.ts
Create mocks
and export handlers:
mkdir mocks
cd mocks
import { getUserAPIMock } from "../api/userAPI.msw.ts";
export const handlers = getUserAPIMock();
These handlers
are referenced in .storybook/preview.ts
. Use the generated SWR hooks in components as usual and MSW will serve responses:
const { data, error, isLoading } = useUsersGetUsers();
Customize mock data
Customize fields via the properties
option:
Example to randomize name/email/image URL:
module.exports = {
"user-api": {
input: {
target: "./openapi.yml",
},
output: {
mode: "split",
target: "./api/endpoints",
schemas: './api/models',
client: "swr",
mock: true,
override: {
mock: {
properties: {
name: () => faker.name.fullName(),
email: () => faker.internet.email(),
'/image/': () => faker.image.url(),
},
}
},
hooks: {
afterAllFilesWrite: "prettier --write",
},
},
},
};
Summary
Development flow:
- Define the API in TypeSpec (
.tsp
). - Generate OpenAPI YAML.
- Use Orval to generate SWR hooks and MSW mocks.
- Develop components in Storybook against the MSW API.