Using Fake JSON Data in Storybook Component Stories
A component story is only as good as the data behind it. A user card story with `name: "Test"` and `email: "a@a.com"` doesn't reveal how the layout handles a 40-character name or a missing avatar — and those are exactly the cases that break in production. Realistic fake data in your stories catches these problems before a designer or reviewer ever sees them.
Step 1: Generate Varied, Realistic Fixtures
Instead of writing one "happy path" object by hand, generate several — including edge cases — using Dummy JSON Generator: a normal user, a user with a very long name, a user with no avatar, a user with a null field. Save these as a fixtures file next to your component.
// UserCard.fixtures.ts
export const normalUser = {
name: 'Priya Nair',
email: 'priya.nair@example.com',
avatarUrl: 'https://i.pravatar.cc/150?u=priya',
role: 'Admin',
}
export const longNameUser = {
name: 'Alessandra Constantina Wetherby-Fitzgerald',
email: 'alessandra.constantina.wetherby.fitzgerald@example.com',
avatarUrl: 'https://i.pravatar.cc/150?u=alessandra',
role: 'Contributor',
}
export const noAvatarUser = {
name: 'Sam Lee',
email: 'sam@example.com',
avatarUrl: null,
role: 'Viewer',
}Step 2: Write One Story per Fixture
Using Storybook's Component Story Format (CSF3), each fixture becomes its own named story — this is what turns "one component, one screenshot" into a real visual regression suite covering edge cases.
// UserCard.stories.ts
import type { Meta, StoryObj } from '@storybook/vue3'
import UserCard from './UserCard.vue'
import { normalUser, longNameUser, noAvatarUser } from './UserCard.fixtures'
const meta: Meta<typeof UserCard> = {
title: 'Components/UserCard',
component: UserCard,
}
export default meta
type Story = StoryObj<typeof UserCard>
export const Default: Story = { args: { user: normalUser } }
export const LongName: Story = { args: { user: longNameUser } }
export const NoAvatar: Story = { args: { user: noAvatarUser } }Step 3: Mock API Calls Inside Stories with MSW
For components that fetch their own data rather than receiving it via props, pair Storybook with the MSW addon so the story intercepts the network call the same way it would in a real app.
npm install msw-storybook-addon --save-devexport const Default: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/user', () => HttpResponse.json(normalUser)),
],
},
},
}Step 4: Add a Loading and Error Story
Two stories developers consistently forget to write are the loading state and the error state — both of which are trivial once your data layer is mocked.
export const Loading: Story = {
parameters: {
msw: { handlers: [http.get('/api/user', async () => { await delay('infinite') })] },
},
}
export const ErrorState: Story = {
parameters: {
msw: { handlers: [http.get('/api/user', () => new HttpResponse(null, { status: 500 }))] },
},
}Common Pitfalls
- Only testing the happy path: the whole point of fake data in stories is covering edge cases — long text, missing fields, zero-state — not just a clean example.
- Hardcoding dates or random IDs in fixtures: use static, fixed values so visual regression snapshots stay stable across runs.
- Not reusing fixtures across stories and tests: the same fixture file should back both your Storybook stories and your Jest/Vitest tests, so they never silently drift apart.
The Bottom Line
Generate a handful of realistic, edge-case-covering fixtures rather than one clean example, wire them into a story per case, and mock any network calls with MSW so components behave exactly as they would in the running app.