Good debugging begins by replacing assumptions with evidence. In the previous lesson, you used fetch() to request JSON, checked response.ok, examined Content-Type, parsed a response body, and handled failures with try/catch. Now you will make that browser–server exchange visible.
This lesson focuses on the Network panel in Chrome DevTools. By the end, you should be able to trigger a request, find it in the network log, and inspect its URL, HTTP method, status, request headers, response headers, returned body, initiator, and basic timing. Plan for about 40 minutes, including a hands-on debugging routine.
Treat the Network panel as the browser’s request ledger
A browser page usually makes far more requests than the one fetch() call you wrote. On an initial load, it might request:
- the HTML document,
- JavaScript modules,
- CSS,
- images and fonts,
- API data,
- analytics or third-party resources.
The Network panel records those requests only while DevTools is open. This explains a common first-time debugging mistake: opening DevTools after the page has loaded and seeing an empty Network panel.
Use this setup sequence every time:
- Open the page you want to inspect.
- Open DevTools with
Control+Shift+Jon Windows/Linux orCommand+Option+Jon macOS. - Choose the Network tab.
- Reload the page, or perform the user action that should cause the request.
For your loadSquad() code from the prior lesson, opening DevTools first and then reloading the page should reveal the request for superheroes.json, among other page resources.
The Network log is not limited to API calls. To focus on browser requests made by fetch() or older XMLHttpRequest code, click the Fetch/XHR filter near the top of the panel. This removes most document, image, stylesheet, and script noise.
Inspect Network Activity - Chrome DevTools 101
Watch “Inspect Network Activity – Chrome DevTools 101” from Chrome for Developers for a compact visual orientation to the Network panel and its request table.
Watch the Network log to see the panel opened, populated by a reload, and interpreted through its core columns. Then watch request details for a quick preview of the per-request inspection tabs.
Read the request list before opening a request
Each row in the Network table represents one resource request. The default columns let you quickly decide where to investigate.
| Column | What it tells you | A useful debugging conclusion |
|---|---|---|
| Name | Resource filename or endpoint identifier | Is this the API route you expected? |
| Status | HTTP status or a browser-level failure marker | Did the server answer successfully? |
| Type | Resource category or MIME type | Is it a fetch request, document, script, image, and so on? |
| Initiator | What triggered the request | Did the page parser, a redirect, or a JavaScript line create it? |
| Size | Delivered response headers and body size | Is the response unexpectedly large or empty? |
| Time | Total request duration | Is this request conspicuously slow? |
| Waterfall | Visual breakdown of when request work occurred | Did it start late or spend a long time waiting? |
The most important distinction from the previous lesson is this:
- A numeric
404or500status means the browser received an HTTP response. - A status such as
(failed)often means the browser could not complete the request. - A
CORS errormeans the browser prevented your frontend JavaScript from using the cross-origin response because the server’s cross-origin policy did not allow it.
So if your UI shows “Could not load squad data,” the Network panel lets you distinguish whether the problem is an invalid URL returning 404, a server exception returning 500, a blocked CORS request, or a genuine connectivity failure. A catch block handles all of these at the UI level, but they demand different fixes.
When a real application creates hundreds of requests, use the Filter input as well as resource-type buttons:
- Enter part of an endpoint path, such as
productsorapi. - Select Fetch/XHR to isolate API activity.
- Clear filters before concluding a request never happened.
- Right-click the table header to add useful columns such as Method, URL, or Domain.
The Chrome DevTools reference below is worth reading now because it explains exactly what the list and the main inspection panels reveal.
Network features reference | Chrome DevTools
Read Chrome for Developers’ “Network features reference” as a working reference for the Network table and the Headers tab. Focus on the information that lets you verify an API contract rather than every optional DevTools feature.
In the “Analyze requests” section, read the request table overview. Pay particular attention to the meanings of Status, Type, Initiator, Size, Time, and Waterfall, and note that you can add Method and URL as columns. Then find “View HTTP headers” and read the headers walkthrough. Follow its sequence for selecting a request and locating General, Response Headers, and Request Headers.
Inspect one API request in depth
Click a request row to open the details panel. The panel’s tabs answer different questions; use the tab that matches your uncertainty.

Headers: what was requested, and what did the server say?
Start in Headers. It has three sections you will use constantly.
1. General
This is the short factual summary:
- Request URL: exact URL that the browser requested.
- Request Method: often
GETfor the JSON request you made in the previous lesson. - Status Code: the HTTP result, such as
200 OK,404 Not Found, or500 Internal Server Error. - Remote Address: server network address and port, when available.
- Referrer Policy: the browser’s policy for what referrer information may be sent.
If you expected a request to /api/products but General shows a different URL, investigate your frontend configuration or string construction before blaming the API.
2. Response Headers
These are metadata sent by the server along with its response. For JSON APIs, first check:
Content-Type: application/json
A realistic value often adds a character encoding:
Content-Type: application/json; charset=utf-8
That is why the prior lesson used:
contentType.includes("application/json");
Other headers you will encounter later include:
Cache-Control, which describes caching behavior.Set-Cookie, which instructs the browser to store a cookie.Access-Control-Allow-Origin, which is relevant when a frontend and API use different origins.
3. Request Headers
These are metadata sent by the browser/client to the server. They can include:
Accept, describing formats the client can accept.Content-Type, especially important when sending JSON in a futurePOSTorPATCHrequest.Origin, which matters for cross-origin browser requests.Authorization, when a frontend later sends a bearer token.Cookie, when the browser sends eligible cookies.
Do not paste sensitive request headers, cookies, bearer tokens, or “Copy as cURL” output into public issue trackers or chat messages. These can grant access to an account or session.
Inspect payloads and returned data
The prior lesson stressed that an HTTP response consists of metadata plus a body. DevTools gives you direct access to both.
Response and Preview
Open Response to inspect the body sent by the server.
For a JSON endpoint, verify the actual structure before writing rendering logic. Suppose your UI expects:
const { products } = await response.json();
In the Response tab, confirm that the body really has this shape:
{
"products": [
{
"id": "p_101",
"name": "Mechanical Keyboard"
}
]
}
If the API actually returned this instead:
[
{
"id": "p_101",
"name": "Mechanical Keyboard"
}
]
then products will be undefined. The request succeeded; your assumptions about the JSON contract did not.
The Preview tab is useful when DevTools can show a friendlier representation of a response. For HTML error pages and images, it can be easier to interpret than raw source. For API debugging, treat Response as the authoritative server body.
Payload
For the GET request you built in the previous lesson, you may see query-string parameters in the Payload tab. For example, a request URL such as:
/api/products?category=keyboard&sort=price
has query parameters category and sort.
Later, when you build create and update endpoints, the Payload tab becomes essential for checking what the browser actually sent in a POST, PUT, or PATCH request. It reveals request bodies and form data, which is especially useful when the server says validation failed.
A practical rule:
Headers explain the request and response metadata; Payload shows what the client sent; Response shows what the server returned.
Find the responsible code and interpret basic timing
Two further tabs turn Network from a viewer into a debugging tool.
Initiator
The Initiator column and tab show what caused the request. In a JavaScript-triggered API call, Chrome often identifies it as Script and can provide a link to the line of code that initiated it.
This helps answer a deceptively important question: Why was this API called at all?
For example, if clicking one “Load products” button creates three identical GET /api/products requests, inspect each request’s initiator. You may discover that:
- the click listener was attached more than once,
- a function is called from both a page-load handler and the click handler,
- or the request runs again during an unintended render cycle.
You will use this skill heavily when React effects enter the course.
Timing and Waterfall
Open Timing for a breakdown of a request’s duration. At this stage, focus on two phases:
- Waiting (TTFB), or Time To First Byte: how long the browser waits for the server to begin responding. This includes network latency and server processing time.
- Content Download: how long the browser takes to receive the response body.
A slow request does not automatically mean a slow Express route. Large TTFB can involve server processing or network delay; large content-download time can point to a large response, slow connection, or browser workload. The Network panel gives evidence first; diagnosing the root cause comes next.
A repeatable inspection routine
Use your prior loadSquad() example for this short lab.
- Open the page, open DevTools, select Network, and click the clear button if an old log is distracting.
- Select Fetch/XHR. Reload the page or invoke
loadSquad()again. - Select the JSON request. In Headers, record its Request URL, method, status, and response
Content-Type. - In Response, verify the top-level properties
squadName,homeTown, andmembers. - In Initiator, locate the script or function responsible for the call.
- In Timing, compare Waiting (TTFB) with Content Download. You are not optimizing yet; simply identify where the visible duration is spent.
- Deliberately change the endpoint to a nonexistent path, reload, and inspect the resulting row. Confirm the
404status in DevTools, then compare it with the error message shown by yourresponse.okguard. - Restore the correct endpoint.
If a request appears missing, work through this quick checklist:
- Was DevTools open before the reload or button click?
- Is recording enabled?
- Is Fetch/XHR hiding a request categorized differently?
- Is text still present in the Filter input?
- Did your JavaScript function actually run? Check the Console and the Initiator column.
- Did a browser cache satisfy the request? For a controlled debugging reload, enable Disable cache while DevTools is open and reload.
Key takeaways
- The Network panel logs browser traffic only while DevTools is open.
- Each row represents one request; Name, Status, Type, Initiator, Size, Time, and Waterfall are your first diagnostic clues.
- Filter to Fetch/XHR when you want to isolate API traffic from page assets.
- In Headers, inspect the exact URL, method, status, request headers, and response headers.
- Use Response to verify the actual JSON or error body sent by the server; successful parsing does not guarantee the shape your UI expects.
- Use Payload to inspect query parameters and request bodies.
- Use Initiator to find the code that triggered a request, and Timing to distinguish waiting from content download.
- A
404or500is an HTTP response;(failed)and CORS errors are different classes of browser-visible failure.
Next, you will move from browser behavior to project workflow: using npm dependencies and scripts to make development commands repeatable across a full-stack project.
Can't find a good explanation? Sign up and we'll make it for you
Sign up