Written by Emmanuel John✏️
With web development constantly evolving, we’ve seen an increasing adaptation to client-server architecture in the ecosystem. While this architecture has many advantages, one of its most common challenges is the time frontend developers spend waiting for the backend team to implement new API endpoints or modify existing ones.
While most teams propose a full-stack development approach to solving this challenge, API mocking has proven to be the most efficient solution.
Mocking allows frontend developers to simulate the responses and behaviors of a live API, such as error handling, timeouts, and specific status codes in real time. Chrome DevTools Local Overrides make this even easier without complex integrations or writing code.
In this tutorial, we will explore how to use Chrome DevTools Local Overrides for API mocking. We’ll mock API response data in a production website without accessing the backend. The tutorial will also cover how to bypass Cross-Origin Resource Sharing (CORS) issues without modifying the server code.
Before moving forward with this tutorial, you should have:
- Knowledge of JavaScript
- Experience building React applications
- Node.js v21 installed
- Chrome browser
Common API mocking libraries
Over the years, the JavaScript ecosystem has developed many libraries for mocking APIs on the browser and Node.js environments. This section will highlight the common tools and libraries for mocking APIs and the limitations of these libraries.
1. Mock Service Worker (MSW)
Mock Service Worker (MSW) is a popular API mocking library that supports both mocking in the browser and Node.js. It allows you to intercept requests and mock corresponding responses.
It supports mocking for RESTful, GraphQL, and WebSocket APIs.
Here is an HTTP request handler for mocking a GET
request with MSW:
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('https://example.com/user', () => {
return HttpResponse.json({
id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d',
firstName: 'John',
lastName: 'Maverick',
})
}),
]
The handler intercepts GET https://example.com/user
requests and then responds with mock JSON data.
Limitations of MSW include:
- Difficulty mocking lower-level module imports like Axios or Fetch directly
- Steeper learning curve for beginners
- Inability to mock APIs with complex relationships
- Difficulties in mocking Cookie responses
2. Axios Mock Adapter
The Axios Mock Adapter is an API mocking library specifically designed for mocking response headers and data for API calls made with Axios. It works on Node.js and also in a browser.
Here is an HTTP request handler for mocking a GET
request with Axios Mock Adapter:
const axios = require("axios");
const AxiosMockAdapter = require("axios-mock-adapter");
const mock = new AxiosMockAdapter(axios);
mock.onGet("/users").reply(200, {
users: [{ id: 1, name: "John Smith" }],
});
mock.onGet
intercepts any GET
request to the specified endpoint and then responds with mock JSON data. It also receives arguments such as status, data, and headers.
Limitations of Axios Mock Adapter include:
- Can’t mock APIs with complex relationships
- Difficulties in mocking file uploads
- Limited to Axios-based projects
- It’s impossible to fully replicate your production API
3. Mirage JS
Mirage JS is my favorite API mocking library. It’s designed to replicate your entire production API server. It ships with an in-memory database and lets you build out fully dynamic features, with data-fetching and persistence logic. Mirage JS uses factories to quickly simulate various server states.
Since 2017, I have been developing critical customer-facing apps with Mirage JS without a backend; all I do is take user stories from our product manager and translate them into fully functional web apps. It is very handy, especially when working under tight deadlines to spin up MVPs efficiently.
Here is an HTTP request handler for mocking a GET
request with Mirage JS:
import { createServer } from "miragejs"
createServer({
routes() {
this.get("/api/users", () => [
{ id: "1", name: "Luke" },
{ id: "2", name: "Leia" },
{ id: "3", name: "Anakin" },
])
},
})
Limitations of Mirage JS include:
- Larger bundle size compared to other API mocking libraries
- It can be overkill for small projects
- No filtering and sorting implementations out of the box
Introducing Chrome DevTools as a mocking tool
This section will cover a brief overview of the tools available in Chrome DevTools, especially for network inspection, debugging, and testing. We’ll also discuss how these tools allow you to inspect, modify, and intercept API calls in real-time.
DevTools Local Overrides
Imagine you're dealing with an issue in your production environment. Maybe there's a typo in an API call, or you're running into an unexpected CORS error but don’t have the privilege to make changes in production. That's where the DevTools Local Overrides feature comes in handy! It lets you temporarily modify resources and experiment with different scenarios right from your browser, without modifying your site in production.
Network panel
The Network tab in Chrome DevTools is a powerful tool for monitoring and debugging network activity in web applications. It provides a detailed view of all network requests made by a webpage.
Benefits of using Chrome DevTools for API mocking
Chrome DevTools Local Overrides provides the following benefits, discussed in further detail below:
- The ability to mock API and test API fixes before they go to production
- Bypassing CORS issues by mocking response headers
- Building interactive prototypes of UI designs without a backend
- The ability to persist mock data or changes in DevTools across page loads
Mocking API responses with Chrome DevTools
This section will cover how to simulate different API responses directly from the browser without needing external mocking services.
Set up Local Overrides
Open DevTools in any production website of your choice, navigate to the Network panel, right-click a request you want to override, and choose Override content from the drop-down menu.
We intend to modify the scoreboard on the goal.com website: Now, DevTools will prompt you to Select a folder in which to store the override files:
After selecting the folder, DevTools will prompt you to grant access rights to it. Click Allow to do so.
Now, local overrides are set up and enabled. DevTools should take you to the Sources panel to let you make changes to web content.
Now we can modify the scoreboard data and refresh the page to see the changes:
Override HTTP requests to mock remote API response
For situations where you are working on a data-driven frontend application and the backend API endpoints are not available, you can mock the API response directly in the browser. This is possible if you already know the data structure for the API response.
Here is a React app that fetches data from the JSONPlaceholder Rest API:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import './App.css';
const App = () => {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/footballers');
setUsers(response.data);
setLoading(false);
} catch (err) {
setError('Failed to fetch data');
setLoading(false);
}
};
fetchUsers();
}, []);
if (loading) return <p className="loading">Loading...</p>;
if (error) return <p className="error">Error: {error}</p>;
return (
<div className="container">
<h1 className="title">User List</h1>
<ul className="userList">
{users.map((user) => (
<li key={user.id} className="userCard">
<p><strong>Name:</strong> {user.name}</p>
<p><strong>Email:</strong> {user.email}</p>
<p><strong>Phone:</strong> {user.phone}</p>
<p><strong>Website:</strong> <a href={`https://${user.website}`} target="_blank" rel="noopener noreferrer">{user.website}</a></p>
</li>
))}
</ul>
</div>
);
};
export default App;
The JSONPlaceholder Rest API does not have the /footballers
endpoint that we called in our React app, so this will result in a 404 error. However, we can mock the response data for this endpoint in our React app while waiting for the JSONPlaceholder backend team to make this endpoint available.
Open Chrome DevTools, navigate to the Network tab and then reload the page. Notice the 404 error in the /footballers
endpoint. Right-click the /footballers
endpoint, and choose Override content from the drop-down menu: You should see the following pane:
Now you can add the following mock data in the above pane:
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna@melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"email": "Nathan@yesenia.net",
"address": {
"street": "Douglas Extension",
"suite": "Suite 847",
"city": "McKenziehaven",
"zipcode": "59590-4157",
"geo": {
"lat": "-68.6102",
"lng": "-47.0653"
}
},
"phone": "1-463-123-4447",
"website": "ramiro.info",
"company": {
"name": "Romaguera-Jacobson",
"catchPhrase": "Face to face bifurcated interface",
"bs": "e-enable strategic applications"
}
},
{
"id": 4,
"name": "Patricia Lebsack",
"username": "Karianne",
"email": "Julianne.OConner@kory.org",
"address": {
"street": "Hoeger Mall",
"suite": "Apt. 692",
"city": "South Elvis",
"zipcode": "53919-4257",
"geo": {
"lat": "29.4572",
"lng": "-164.2990"
}
},
"phone": "493-170-9623 x156",
"website": "kale.biz",
"company": {
"name": "Robel-Corkery",
"catchPhrase": "Multi-tiered zero tolerance productivity",
"bs": "transition cutting-edge web services"
}
}
]
Reload the page and you should have the mocked data rendered in your React app:
Override HTTP response headers
You can also override response headers, which is particularly useful for testing CORS issues or other security-related header changes.
For instance, if a page encounters a CORS error preventing data from loading, it often requires server-side adjustments. While waiting for the backend team to resolve the issue, you can temporarily modify the headers yourself to test and continue your development without delays: Navigate to the Network tab then right-click the endpoint with the CORS issue, and choose Override headers from the drop-down menu:
Click Add header then add *
Access-Control-Allow-Origin
**and set its value to ``: Reload the page and the CORS error will be gone:
Persisting mock data
Chrome Local Override automatically persists mocked data and stores other overridden resources in your drive.
Navigate to the Sources tab, then click Overrides. Right-click the overridden file, choose Open in containing folder from the drop-down menu:
You can right-click to open the folder and edit the files using your favorite code editor. Even better, you can sync the folder to a shared location, making it easy to collaborate and share with your colleagues.
When to continue using API mocking libraries
While Chrome DevTools allows you to mock APIs without writing any code, there are many scenarios where external API mocking libraries are a better choice:
Test automation
External libraries like MSW and Mirage JS allow you to programmatically mock APIs in unit and integration tests. Chrome DevTools doesn’t support test automation.
Working with multiple browsers
Chrome DevTools is limited to Chromium-based browsers only while external libraries are browser-agnostic.
CI/CD
When working with CI/CD pipelines for test automation, external libraries are better choices as DevTools doesn’t support CI/CD workflows.
Sharing across teams
If you need to share your mock setups across teams, external libraries are preferable because it’s easy to share code via Git.
Conclusion
In this tutorial, we explored common API mocking libraries, their limitations, and how to use DevTools Local Overrides for API mocking in a production website without accessing the backend. We also covered how to bypass CORS issues without modifying the server code, and when to still use API mocking libraries.
If you're prototyping UI designs without a backend or testing API fixes before they go live, you should consider trying out Chrome DevTools Local Override. You'll be surprised at how much easier your tasks can be!
Get set up with LogRocket's modern error tracking in minutes:
- Visit https://logrocket.com/signup/ to get an app ID.
- Install LogRocket via NPM or script tag.
LogRocket.init()
must be called client-side, not server-side.
NPM:
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
Script Tag:
Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>
3.(Optional) Install plugins for deeper integrations with your stack:
- Redux middleware
- ngrx middleware
- Vuex plugin
Top comments (0)