JSON viewer
A collapsible, syntax-colored JSON tree with search, filtering, copy for any value or its path, and optional inline editing.
Delivered to Cedarline ERP200 OK in 212 ms
Arrow keys move between rows and open or close them. C copies a value, P copies its path. Slash searches.
import { JsonViewer } from "@oration/canon/components/json-viewer";import { StatusLabel } from "@oration/canon/components/status-dot";export function Hero() { const payload = { id: "evt_8Kp3Vd", type: "call.analyzed", created_at: "2026-09-28T15:42:09Z", data: { call_id: "call_7Hq2Nw", agent: { id: "agt_payment_status", name: "Payments desk" }, caller: { phone: "+13125550142", vendor_id: "V-10482" }, duration_ms: 184200, analysis: { intent: "payment_status", resolved: true, invoice_numbers: ["INV-20931", "INV-20947"], amount_discussed: 20625, follow_up_required: false, callback_requested_at: null, payment: { status: "scheduled", method: "ACH", run_date: "2026-09-29", }, }, }, }; return ( <div className="flex w-full max-w-lg flex-col gap-2"> <p className="flex items-center justify-between gap-3 text-13"> <span className="font-medium text-foreground"> Delivered to Cedarline ERP </span> <StatusLabel tone="success">200 OK in 212 ms</StatusLabel> </p> <JsonViewer title="Request body" value={payload} defaultExpandDepth={2} /> </div> );}Usage#
JSON viewer shows a payload people inspect as a collapsible tree: quoted keys, braces and commas, so it reads and copies like real JSON, with values colored by type. Every row copies its value or its JSONPath ($.data.analysis.payment.method), the toolbar folds or opens everything, and search finds keys, values and paths, then filters the tree down to the matches. Pass the value itself, never JSON.stringify output: the viewer needs the structure to fold, search and copy paths. With editable, every key and value edits where it stands, in the same type and type size, so a person adjusting a mock response never leaves the document they're reading.
When to use
- For a payload people inspect: a webhook request body, an API response, a tool call's input and output, an audit log event.
- For structured output people check field by field, such as post-call analysis or a mapped caller lookup.
- For a response body that may or may not be JSON. Pass the string; text that isn't JSON renders as written.
- Inside a card use
variant="well"; inside another well, such as Tool chip, usevariant="bare". - With
editable, for JSON people adjust in place: a tool's mock response, test values for a call, a sample webhook body. Passbaselineand pair it with a save bar.
When not to use
- For a request people run, such as a curl command, or a URL and headers. Use Code block
- For defining fields, their types, descriptions and whether they're required. That's a schema, not a document. Use JSON schema builder
- For a handful of labeled fields people read rather than inspect. Lay them out as a description list. Use Settings section
- For a before-and-after of fields. Use Diff
The Machine Mono Rule
The Tint Well Rule
variant="well", never a raised block inside a raised card.Syntax inks
The Quiet Indigo Rule
Anatomy#
Arrow keys move between rows and open or close them. C copies a value, P copies its path. Slash searches.
- Title. 12px medium Slate Meta in a 36px bar with a hairline bottom. Name what the payload is: Request body, Response 200, analysis.json.
- Summary. The root's size in 12px tabular figures: 5 keys, 240 items, or Empty.
- Toolbar. 24px ghost icon buttons with tooltips: search (from 10 values up), expand all and collapse all (when anything nests) and copy the whole document. Expand all and collapse all disable when they would do nothing.
- Chevron and guides. A 12px chevron that turns 90° as a branch opens, in a 16px column. Each level indents 16px and draws a hairline guide under its parent's chevron.
- Key and value. 12px Geist Mono at a 20px line. Long strings wrap at the row's indent; past 280 characters they clip with Show all 1,240 characters.
- Collapsed summary. A folded branch reads
{ 3 keys }or[ 2 items ], the count in a 4px-corner ink chip. Clicking it, the key or the chevron opens the branch. - Inline editor. Editable only. A field in the same 12px mono, color and line as the text it replaces, on White Plane with a 1px indigo ring and a soft 3px halo drawn as a shadow, so rows never shift. String quotes stay outside it.
- Type chip. Editable only. A 20px Slate Meta chip after the value naming its type, String or Number, with a menu of all six. New fields and nulls read Detect from value until you pick one.
- Unsaved dot. With
baseline, a 5px indigo dot in the gutter beside each field that differs from it, and beside a folded branch with a change inside. - Add key. Editable only. A quiet Slate Meta row that closes the document: a plus and Add key (or Add item for an array).
Examples#
Editable
Click a value or key to edit it where it stands, a boolean to flip it, or Add key to append. The type chip beside a field changes its type. baseline marks unsaved fields with the indigo dot until Save.