JSON view
Shows structured output as a foldable tree the person can search and copy from.
Examples
Path
$Path
$Chrome
- Path
$fulldefault
plain
States
open
closed
Usage
When to use it
- Use
- A tool result, a run payload or a trace span carries nested data the person inspects.
- Use
- The person needs the path to a value for code, a jq filter or a bug report.
- Not for
- The data is a flat list of fields with labels. Use Data list.
- Not for
- The data is code or config the person reads as text. Use Code block.
- Not for
- The data is many rows of the same shape. Use Table.
Rules
7 rules
- Must
- Pass the parsed value in data; never a JSON string. Because a string renders as one long string leaf, so nothing folds and nothing is searchable by key.
- Must
- Pass label as a noun phrase that names the payload: "issue_refund result". Because it names the tree and the search field for a screen reader, and the default "JSON" says nothing about which payload this is.
- Never
- Pass a payload that holds a live secret, a token or a full key. Because the view renders every value as text, including in search and in the copy button, and shows no mask.
- Should
- Set defaultExpandDepth to the level that fits the first screen; 0 starts closed. Because a fully open 500-key payload buries the part the person came for, and a closed one hides it.
- Should
- Turn toolbar off for a payload under about 10 rows. Because a search field over ten lines costs 40px and finds nothing the eye misses.
- Should
- Set maxHeight when the view sits in a page with other content; the tree scrolls inside. Because the default 420px keeps one payload from pushing the rest of a detail page off screen.
- Should
- Pass refs for the resource IDs in the payload so they take their kind color. Because IDs found by default are underlined in their kind hue, and refs adds the ones whose shape the default does not know.
Accessibility
5 checks
- The tree follows the WAI-ARIA tree pattern: one tab stop, role="tree" with treeitems, aria-level and aria-expanded.
- The search field is named "Search <label>", announces "2 of 7" or "No matches" politely, and has a clear button.
- A body wider than its box becomes its own tab stop so keyboard users can scroll it.
- The current match gets a pressed fill and, in forced colors, an outline.
- Icon buttons are named (Open all, Close all, Copy JSON); focus shows a 2px ink outline.
Keyboard
6 keys
- ArrowDown, ArrowUp
- Moves to the next or previous visible row.
- ArrowRight
- Opens a closed branch; on an open one, moves to its first child.
- ArrowLeft
- Closes an open branch; otherwise moves to the parent.
- Home, End
- Moves to the first or last visible row.
- Enter, Space
- Toggles a branch, or unfolds a long string.
- Enter in search
- Steps to the next match; Shift+Enter goes back, Escape clears.
Edge cases
9 edge cases
- String over 120 characters
- Folds to its first 80 with a "+n chars" button.
- Closed branch
- Says how much it hides: "3 keys" or "5 items".
- Searching
- Opens the branches that hold a match and hides the rest; Open all and Close all are disabled.
- No match
- Says "Nothing matches" with the query in a code tag.
- Key with a space or slash
- The footer path uses bracket form: $["user agent"].
- Empty object or array
- Renders {} or [] on one row with no caret.
- Right to left page
- The tree stays left to right, as code does.
- Forced colors
- The current match keeps an outline, since its fill is lost.
- Zoom 200%
- Rows stay 24px tall; long lines scroll sideways inside the body.
API
8 props
dataunknowndefaultrequiredlabelstringdefault'JSON'defaultExpandDepthnumberdefault2toolbarbooleandefaulttruecopybooleandefaulttruepathbooleandefaulttoolbarmaxHeightnumberdefault420refsCodeRef[]
Tokens
13 tokens
--code-text- var(--ink)
--code-string- oklch(var(--ink-c) / var(--code-string-alpha))
--code-comment- oklch(var(--ink-c) / var(--code-comment-alpha))
--surface-page- var(--paper)
--surface-hover- oklch(var(--ink-c) / 0.05)
--surface-pressed- oklch(var(--ink-c) / 0.08)
--line-frame- oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row- oklch(var(--ink-c) / 0.08)
--row-sm- 32px
--type-code- 400 13px/20px var(--font-mono)
--type-tag- var(--type-code-sm)
--dur-fast- 120ms
--ease-step- cubic-bezier(0.2, 0, 0, 1)