Skip to content

How to apply MSW mocking in Next.js server component? #2451

@katanazero86

Description

@katanazero86
// src/components/ExampleServer.tsx

export default async function ExampleServer() {
    const res = await fetch('/api/example');
    const {message} = await res.json();

    return (
        <div>
            <h1>Server Side API Call</h1>
            <p>{message}</p>
        </div>
    );
}
// src/mocks/browser.ts
import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)
// src/mocks/node.ts
import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)
// src/mocks/handlers.ts
import {http, HttpResponse, passthrough} from 'msw'

interface User {
    id: number
    name: string
}

export const handlers = [
    http.get('/api/example', () => {
        return HttpResponse.json({message: 'Hello, MSW!'});
    }),

    http.get('/api/users', () => {
        const users: User[] = [
            {id: 1, name: 'John'},
            {id: 2, name: 'Jane'},
        ]
        return HttpResponse.json(users)
    }),

    http.post('/api/users', async ({request}) => {
        const newUser = await request.json() as Omit<User, 'id'>
        return HttpResponse.json({id: 3, ...newUser} as User, {status: 201})
    }),

    http.get('*', ({request}) => {
        console.log('url', request.url);

        if (/\.(png|jpg|jpeg|gif|svg)$/.test(request.url)) {
            return passthrough();
        }

        return passthrough();
    }),
]
// src/mocks/index.ts
async function initMocks() {
    if (typeof window === 'undefined') {
        console.log("Initializing msw by server");
        const {server} = await import('./node')
        server.listen({
            onUnhandledRequest: 'bypass',
        })
    } else {
        console.log("Initializing msw by browser");
        const {worker} = await import('./browser')
        await worker.start({
            onUnhandledRequest: 'bypass',
        })
    }
}

export default initMocks
/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental:{
        instrumentationHook: true,
    }
};

export default nextConfig;
// src/instrumentation.ts
// import {server} from './mocks/node'; // module not found

export async function register() {
    if(process.env.NEXT_RUNTIME === 'nodejs' && process.env.NODE_ENV === 'development') {
        const { server } = await import('./mocks/node')
        server.listen({
            onUnhandledRequest: 'bypass',
        });
    }
}

How do I apply MSW mocking in Next.js server components?

I set it up like above. The client side is mocked normally, but the server component is not. And I get an error like [MSW] Failed to apply interceptor: the global WebSocket property is non-configurable. This is likely an issue with your environment. If you are using a framework, please open an issue about this in their repository.

Is there a solution or workaround?

I followed this link: mswjs/examples#101 but I still failed. Please help!

git url: https://github.com/katanazero86/nextjs-msw

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions