JSON HTML Viewer: Inspect the Value and Keep Its Exact Location

You open a nested JSON record and see “007,” false, zero, and null. If the viewer drops false-looking values or turns the identifier into a number, the display has changed the record you wanted to inspect.

A JSON HTML viewer should make object branches, array indexes, and scalar types visible while keeping the pasted source available. The original inspection fixture below gives you a small, concrete way to test those distinctions. Use it to inspect the bounded local HTML viewer, then verify its behavior in the intended host.

JSON HTML Viewer · Typed values and paths
JSON HTML Viewer · Typed values and paths
Open the full example ↗

Start with a record that exposes type mistakes

{
  "items": [
    {"id": "007", "active": false, "count": 0, "note": null}
  ],
  "a/b": {"~key": "<b>literal</b>"},
  "empty": []
}

The root is an object with three properties. Its items property is an array with one element, at index zero. That element is an object with four properties.

Selected member Type Displayed value
items, index 0, id String "007"
items, index 0, active Boolean false
items, index 0, count Number 0
items, index 0, note Null null
empty Array [] with zero elements

None of those scalar values means “missing.” The string identifier retains both leading zeros. An empty object would instead display {} with zero properties; it is not interchangeable with an empty array.

MDN's JSON.parse reference identifies the possible parsed root types and syntax errors. Accept scalar roots as well as object and array roots; a root false or null does not require an invented object wrapper.

Describe location with typed path tokens

A slash-separated display can become ambiguous when a property name itself contains a slash. Use an original path record that distinguishes object keys from array indexes:

[{"key":"items"},{"index":0},{"key":"id"}]

That path selects the string "007". Selecting the HTML-looking string uses:

[{"key":"a/b"},{"key":"~key"}]

The slash and tilde are literal characters in property names. An object property named "0" uses a key token, while array position zero uses an index token. An empty token list means the root.

This is a custom inspection path, not JSON Pointer or JSONPath. Give it that label so someone copying the record does not expect another tool to interpret it as a standard query language.

Build a typed projection without replacing the raw text

Use JSON.parse in a try/catch without a reviver. After parsing, traverse only own object properties and actual array elements. Do not merge the parsed object into application configuration or use inherited properties as branches. Even a property called "proto" remains a literal inspected key; it is not an instruction to alter another object.

Native details/summary branches can show object property counts and array element counts. Scalar selection controls update a separate typed value and path record. Use textContent for labels, keys, values, and paths. The string <b>literal</b> must appear as text with angle brackets, not as a bold element. Never construct executable input through eval or inject values through innerHTML.

Keep a visible warning before Parse: this tree is a JavaScript parsed projection, and the pasted source remains authoritative. MDN notes that JSON numbers can lose precision when converted to JavaScript numbers. RFC 8259 also describes interoperability problems involving duplicate property names and visible member ordering.

The viewer does not detect every duplicate key, recover lexical number spelling, or reproduce original source bytes. A reserialized tree is not a lossless replacement for the pasted record. Keep the raw field intact for checks involving those details.

Declare the numeric and display limits

Reject a parsed number if it is nonfinite, or if it is an integer outside JavaScript's safe-integer range. Suggest quoting a large identifier at its source when its purpose is textual identity, while keeping the original record available. Do not silently rewrite its type.

For example, an unquoted integer 9007199254740993 is outside this numeric scope; the quoted string "9007199254740993" can be inspected as a string. Ordinary decimal numbers may still have binary floating-point approximation, so the rejection rule is not a proof that every accepted number preserved its original digits.

Limit input to 20,000 UTF-16 code units before parsing. After parsing, check maximum depth 20 and maximum node count 500 before constructing the tree. Count the root as one node at depth zero and every property value or array element as another node. A property name does not count as a separate value node. The fixture above has ten nodes and maximum depth three.

These are bounded display rules, not a streaming parser or proof against every resource-exhaustion problem. If parsing, traversal limits, or numeric checks fail, clear the old tree and selected path and show a text error. Do not truncate the input into a seemingly valid partial record.

Any input edit invalidates the old projection until Parse succeeds again. Clear empties the source, tree, selection, and error. This paste-only design has no file upload, remote fetch, storage, export, or automatic redaction feature.

Copyable viewer prompt

Create an original self-contained HTML/CSS/JavaScript paste-only JSON inspector with readable source and an acceptance-test report. Use JSON.parse in try/catch, no reviver, eval, Function, fetch, file upload, storage, export or redaction. Before Parse, show that parsed projection may lose duplicate-key detail, source ordering/lexical form and numeric precision; raw pasted text remains authoritative.

Fixture:
{"items":[{"id":"007","active":false,"count":0,"note":null}],"a/b":{"~key":"<b>literal</b>"},"empty":[]}

Use native details/summary for own object properties and array elements, with explicit type/count labels. Scalars and scalar roots remain typed: string "007", boolean false, number 0, null distinct; [] differs from {}. Native selection shows value/type and custom token path. Root path []; id path [{"key":"items"},{"index":0},{"key":"id"}]; literal property path [{"key":"a/b"},{"key":"~key"}]. Object key "0" differs from array index 0. Do not call this JSON Pointer/JSONPath.

Render every key/value/path with textContent, never innerHTML or generated links. Keep "__proto__" as literal own key; no prototype/config merging or inherited-property traversal. Input bound 20000 UTF-16 code units before parse. After parse enforce depth 20 (root 0) and 500 nodes (root counts 1; each value counts 1; keys not separate) before tree construction. Fixture has 10 nodes/depth 3.

Reject parsed nonfinite numbers and integer values outside safe-integer range; do not silently convert type. Test unquoted 9007199254740993 rejected, quoted string accepted; warn ordinary decimals can still approximate. Raw input stays untouched. Edits/errors invalidate old tree/path; Clear empties source/projection/selection/error. No partial truncation, duplicate detection, exact-byte roundtrip or complete resource/security guarantee.

Test fixture branches, scalar roots, false/zero/null, empty containers, typed paths, literal HTML-looking text, malformed input, numeric and size/depth/node limits, focus, actual article width and 360 px. Mark unexecuted runtime/security checks not_tested.

Keep the source beside the inspection view

Retain the raw JSON and native viewer source when using a path record to investigate a field. For an optional prepared HTML version in NOS, its supplied product evidence supports HTML saving and rendering; verify parsing, literal-text display, and branch controls in the actual workspace before calling that version a tested viewer. Explore NOS with prepared HTML, keeping the raw record beside the typed projection so an inspection result never quietly replaces its source.

Keep reading