A tool for intercepting network requests at the browser level. Allows frontend development independent of backend readiness using typed mocks.
Benefits: Allows testing error scenarios, network delays, and various data states without a real backend.
src/entities/[entity-name]/handlers/. Files named [entity-name].handlers.ts. Contain logic for intercepting entity-specific requests.src/entities/[entity-name]/mock/. Files named [entity-name].mock.ts. Contain static or dynamic data simulating a server response.src/shared/api/msw/. All handlers are registered in handlers.ts.types/ folder for typing.1import { type IEntity } from "../types";
2
3export const ENTITY_MOCK: IEntity[] = [
4 {
5 id: "1",
6 fullName: "John Doe",
7 date: "2024-03-22",
8 status: "active"
9 },
10 {
11 id: "2",
12 fullName: "Jane Smith",
13 date: "2024-03-21",
14 status: "pending"
15 }
16];msw library to intercept specific URLs. You can also simulate network delay or server errors here.1import { HttpResponse, http } from "msw";
2import { ENV } from "@/shared/config";
3import { ENTITY_MOCK } from "../mock";
4
5export const entityHandlers = [
6 http.get(`${ENV.VITE_API_URL}/entity/list`, () => {
7 return HttpResponse.json({
8 data: ENTITY_MOCK
9 });
10 }),
11
12 http.post(`${ENV.VITE_API_URL}/entity/update`, async ({ request }) => {
13 const body = await request.json();
14 return HttpResponse.json({ success: true, data: body });
15 })
16];shared/api/msw/browser.ts to intercept browser requests.1import { setupWorker } from "msw/browser";
2import { handlers } from "./handlers";
3
4export const worker = setupWorker(...handlers);shared/api/msw/handlers.ts.1import { entityOneHandlers } from "@/entities/entity-one/handlers";
2import { entityTwoHandlers } from "@/entities/entity-two/handlers";
3
4export const handlers = [
5 ...entityOneHandlers,
6 ...entityTwoHandlers
7];app/init/msw.ts that checks environment flags.1import { ENV } from "@/shared/config";
2
3export const initMsw = async () => {
4 if (import.meta.env.DEV || ENV.VITE_ENABLE_MSW === "true") {
5 const { worker } = await import("@/shared/api/msw/browser");
6 return worker.start({
7 onUnhandledRequest: "bypass"
8 });
9 }
10 return Promise.resolve();
11};src/main.tsx.1import { StrictMode } from "react";
2import { createRoot } from "react-dom/client";
3import { initMsw } from "./app/init/msw";
4import App from "./app";
5
6const container = document.getElementById("root");
7
8if (container) {
9 const root = createRoot(container);
10
11 initMsw().then(() => {
12 root.render(
13 <StrictMode>
14 <App />
15 </StrictMode>
16 );
17 });
18}.env file.1VITE_ENABLE_MSW=true