Request Viewer

Network request inspector showing headers, response body, and timing waterfall. Designed for dev dashboards, API documentation, and debugging tools.

lucide-react

Preview

GEThttps://api.github.com/repos/vercel/next.js200 OK247ms

Request Headers

Acceptapplication/vnd.github.v3+json
AuthorizationBearer ghp_****••••••••
User-Agentjalco-dashboard/1.0
Cache-Controlno-cache

Response Headers

Content-Typeapplication/json; charset=utf-8
X-RateLimit-Limit5000
X-RateLimit-Remaining4987
X-GitHub-Request-IdC4F2:3A1E:1B4F2A8:2D5E1C0:65A1B2C3
ETag"abc123def456"
Cache-Controlprivate, max-age=60, s-maxage=60

Installation

$ shadcn add https://ui.justinlevine.me/r/request-viewer.json

Usage

import { RequestViewer } from "@/components/request-viewer"
<RequestViewer request={networkRequest} />

Display-only. This component never makes network requests or executes API calls. You supply a static NetworkRequest object and it renders the data — nothing is fetched, resolved, or executed at runtime.

How to populate

Since RequestViewer is display-only, you need to supply the data yourself. Here are three common approaches:

  • Hardcode a static object. Define a NetworkRequest inline or in a separate file. Good for API docs, example pages, and design system demos where the data doesn't change.
  • Load from a JSON file. Save request data as .json and import it. You can export requests from browser DevTools (Network tab → right-click → Copy as HAR) and transform the HAR entry into a NetworkRequest shape, or just save the object directly.
  • Capture from your own fetch calls. Wrap your fetch calls to record timing and headers into a NetworkRequest object, then pass it to the viewer. The component never triggers the request — your code does, separately, and hands the result over.
import requestData from "./fixtures/github-api.json"
<RequestViewer request={requestData} />

Examples

HTTP methods

GET — Success

GEThttps://api.github.com/repos/vercel/next.js200 OK247ms

Request Headers

Acceptapplication/vnd.github.v3+json
AuthorizationBearer ghp_****••••••••
User-Agentjalco-dashboard/1.0
Cache-Controlno-cache

Response Headers

Content-Typeapplication/json; charset=utf-8
X-RateLimit-Limit5000
X-RateLimit-Remaining4987
X-GitHub-Request-IdC4F2:3A1E:1B4F2A8:2D5E1C0:65A1B2C3
ETag"abc123def456"
Cache-Controlprivate, max-age=60, s-maxage=60

POST — Created

POSThttps://api.example.com/v1/users201 Created312ms

Request Headers

Content-Typeapplication/json
AuthorizationBearer eyJhbGci••••
X-Request-IDreq_8f3a2b1c

Response Headers

Content-Typeapplication/json
Location/v1/users/usr_7k2m9p
X-Request-IDreq_8f3a2b1c

DELETE — Not Found

DELETEhttps://api.example.com/v1/users/usr_expired404 Not Found89ms

Request Headers

AuthorizationBearer eyJhbGci••••
Acceptapplication/json

Response Headers

Content-Typeapplication/json
X-Error-CodeUSER_NOT_FOUND

Default tab

Start on Response

GEThttps://api.github.com/repos/vercel/next.js200 OK247ms
application/json; charset=utf-8246 B
{
  "id": 70107786,
  "name": "next.js",
  "full_name": "vercel/next.js",
  "stargazers_count": 128450,
  "language": "JavaScript",
  "default_branch": "canary",
  "topics": [
    "nextjs",
    "react",
    "framework",
    "ssr",
    "web"
  ]
}

Start on Timing

GEThttps://cdn.example.com/assets/bundle.js200 OK1.24s
Total Duration1.24s
DNS Lookup
45ms
TCP Connect
62ms
TLS Handshake
85ms
Request Sent
500µs
Waiting (TTFB)
320ms
Content Download
728ms
DNS Lookup
TCP Connect
TLS Handshake
Request Sent
Waiting (TTFB)
Content Download

API Reference

RequestViewer

PropType

HeaderEntry

PropType

TimingEntry

PropType

Notes

  • No network activity. This component does not call fetch, open sockets, or execute any API calls. It renders the data you pass in — nothing more.
  • Client component. Uses "use client" for tab switching state only.
  • JSON formatting. Response bodies that look like JSON are automatically pretty-printed.
  • Status colors. Status badges are color-coded: 2xx green, 3xx blue, 4xx amber, 5xx red.