Mock GraphQL queries & mutations in Next.js with MSW — No Backend, No Problem
1. Introduction
Mock GraphQL queries & mutations in Next.js with MSW — No Backend, No Problem
1. Introduction
API mocking has become an essential part of modern frontend development workflows. Whether you’re working solo, collaborating with backend teams, or building complex UI flows in Storybook, mocking allows you to move fast without waiting for the backend to be ready.
🧪 Why mock APIs?
- Local development without backend dependencies No need to spin up Docker containers or wait for the backend to be deployed, your frontend can work with realistic mock data instantly.
- Faster UI iteration and testing Mocking lets you simulate different scenarios like loading states, empty data, success messages, or server errors, all without touching real APIs.
- Better DX in Storybook and unit tests Need to demo a component in isolation? Mocking GraphQL queries makes it trivial to generate dummy data and showcase real UI behavior in controlled environments.
🎯 What this article is about
This is a step-by-step guide to mocking GraphQL queries and mutations using MSW (Mock Service Worker) in a Next.js 15 App Router project.
We’ll walk through:
- Installing and initializing MSW
- Writing mock handlers for GraphQL operations (query + mutation)
- Configuring the service worker to run in the browser
- Using environment variables to toggle mocks on/off in dev
🚫 What this article won’t cover
- Setting up a Next.js project (we assume you already have one)
- Apollo Client configuration (we assume your GraphQL layer is working)
- Server-side mocking (setupServer), we’re keeping it client-only for simplicity
2. Requirements
- next@15.x with App Router
- react@19.x
- @apollo/client@3.x
Instal MSW:
npm install msw - save-dev
Then initialize it:
npx msw init public --save
This creates the mockServiceWorker.js file in your /public folder. MSW uses this service worker to intercept real network requests in the browser, and return mocked responses instead.
3. Setting Up GraphQL Handlers
In MSW, a handler defines how to intercept and respond to a specific type of request, whether it’s REST, a GraphQL query, or a mutation.
Let’s mock a GraphQL query and a mutation for a fictional User Management module.
Tip: Use Faker for Realistic Mock Data
Instead of hardcoded mock JSON, use a library like @faker-js/faker to generate fake but realistic data.
npm install @faker-js/faker --save-dev
➡️ src/mocks/graphql/handlers.ts
import { graphql, HttpResponse } from 'msw';
import { faker } from '@faker-js/faker';
export const userHandlers = [
graphql.query('GetUsers', () => {
console.log('Captured GetUsers query.');
const users = Array.from({ length: 10 }, () => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
}));
return HttpResponse.json({
data: { users },
});
}),
graphql.mutation('CreateUser', ({ variables }) => {
console.log('Captured CreateUser mutation:', variables);
const { name, email } = variables;
return HttpResponse.json({
data: {
createUser: {
id: faker.string.uuid(),
name,
email,
},
},
});
}),
];
4. Browser-Only Setup
➡️ src/mocks/browser.ts
import { setupWorker } from 'msw/browser';
import { userHandlers } from './graphql/handlers';
export const worker = setupWorker(...userHandlers);
❗ MSW only runs in the browser. Server-side rendering (SSR) is not intercepted. That’s perfect for Storybook, local development, or client-only apps.
5. Enabling Mocking Conditionally with MSWProvider
To start MSW only when mocking is enabled (e.g., in local dev or Storybook), we wrap the setup in a simple React provider.
🤔 Why a Provider?
Next.js 15 (App Router) encourages modular architecture. A provider lets us: • Run setup once on the client • Suspend rendering until MSW is ready (to avoid premature API calls) • Keep layout.tsx clean and declarative • Toggle mocking via .env without affecting production
➡️ src/providers/MSWProvider.tsx
'use client';
import React, { ReactNode, Suspense, use } from 'react';
const enabledMocks = process.env.NEXT_PUBLIC_API_MOCKING === 'enabled';
const mockingEnabledPromise =
enabledMocks && typeof window !== 'undefined'
? import('@/mocks/browser').then(async ({ worker }) => {
await worker.start({
onUnhandledRequest(request, print) {
if (request.url.includes('_next')) return;
print.warning();
},
});
})
: Promise.resolve();
export function MSWProvider({ children }: { children: ReactNode }) {
return (
<Suspense fallback={null}>
<MSWProviderWrapper>{children}</MSWProviderWrapper>
</Suspense>
);
}
function MSWProviderWrapper({ children }: { children: ReactNode }) {
if (enabledMocks) {
use(mockingEnabledPromise);
}
return children;
}
🛑 onUnhandledRequest is a great debug helper — it logs a warning in the console when your app makes an unmocked GraphQL call.
To enable mocks locally:
➡️ .env.local
NEXT_PUBLIC_API_MOCKING=enabled
6. Simple Integration in App Layout
Even though the logic to start the worker is inside the provider, we still need to conditionally render the MSWProvider in layout.tsx.
🤔 Why?
To avoid: • Importing MSW in production • Bundling extra mocking logic unnecessarily • Any chance of mock leaking into prod
Think of it as a guard clause at the layout level to ensure mocking is opt-in and doesn’t leak into unintended builds.
➡️ src/app/layout.tsx
import { MSWProvider } from '@/providers/MSWProvider';
import { ApolloProviderWrapper } from '@/providers/ApolloProvider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{process.env.NEXT_PUBLIC_API_MOCKING === 'enabled' ? (
<MSWProvider>{children}</MSWProvider>
) : (
children
)}
</body>
</html>
);
}
7. Example Queries
Once everything is wired up, your mocked GraphQL calls might look like this:
import { gql, useQuery, useMutation } from '@apollo/client';
const GET_USERS = gql`
query GetUsers($searchTerm: String, $limit: Int) {
users(searchTerm: $searchTerm, limit: $limit) {
id
name
email
}
}
`;
const CREATE_USER = gql`
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
}
}
`;
Use them in your component as usual, MSW will intercept the calls and return mock data. Fast and test-friendly 🚀
8. Final Thoughts
Mocking GraphQL in Next.js using MSW gives you: • ⚡ Speedy frontend development • ✅ Reliable Storybook demos • 🔧 Full control over mock data • 🚨 Warnings when mocks are missing
Full Example
Explore the complete working project here **github.com/dalvarado86/msw-graphql-example**
메타데이터
- post_id
- 863fe385eb00
- slug
- mock-graphql-queries-mutations-in-next-js-with-msw-no-backend-no-problem-863fe385eb00
- url
- https://medium.com/@alvarado.david/mock-graphql-queries-mutations-in-next-js-with-msw-no-backend-no-problem-863fe385eb00
- canonical_url
- https://medium.com/@alvarado.david/mock-graphql-queries-mutations-in-next-js-with-msw-no-backend-no-problem-863fe385eb00
- author_url
- https://medium.com/@alvarado.david
- status
- ok
- fetched_at
- 2026-06-24 16:30:55