ComfyUI Node Runs on cloud

Content Viewer

The any-type output inspector that renders almost everything

By WASasquatch·Created 3 years ago·Updated a day ago· 1,839
Content Viewer
  • content
  • content
manual_content
viewer_meta{"lastInputHash": "", "excluded": []}
view_state{}
hold_for_editfalse
hold_timeout600

You know that moment where a node hands you a big JSON blob or a pile of text and the only way to read it is to shrink the node to nothing and squint? Content Viewer (class WASComfyViewer) is the cure. It's an output inspector that takes any type - string, list, dict, image tensor, whatever - and renders it in a sandboxed iframe with a view auto-picked for what you fed it. It's from WASasquatch, the same author as the giant WAS Node Suite toolkit, so it has that pack's polish behind it. The kicker: it's not just a debug tool. People genuinely use it as a notes/documentation node living inside their workflows.

How it works

Plug anything into its single content input and the node serializes it (JSON for objects, plain text for strings), hashes it, and ships it to the frontend. Twelve built-in "views" each run a detect() on the content and score how well they match; the highest-priority winner renders it. Feed it an <svg tag and you get SVG, <!DOCTYPE html and you get full HTML with scripts, { or [ and you get a collapsible syntax-highlighted JSON tree. Markdown gets the full treatment with Mermaid diagrams and KaTeX math, and ANSI escape codes light up a terminal view instead of raw garbage. Priority matters: an IMAGE tensor matches both the Canvas compositor and the Object inspector, so a selector appears and you pick your poison.

Two details worth knowing. First, it's a passthrough: the content output re-emits what came in, so you can drop it mid-chain without breaking your graph. Second, content priority is user edits > backend execution > connected content. If you click Edit and type something in, that's what you see - your manual text wins until you clear it. That's exactly why it doubles as an annotation node.

The input that matters

Just one, and it's typed *, meaning any socket in ComfyUI fits:

  • content - the anything-port. Lists are supported and render as indexed containers with per-item checkboxes (to filter what flows on) and copy buttons.

The Edit control is the secret weapon: type Markdown or HTML, hit Save, and you've got rich documentation sitting in your workflow that persists with it. Download grabs single content with the right extension (.html, .svg, .md…) and zips lists.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/ComfyUI_Viewer.git

Then restart ComfyUI. ComfyUI Manager works too - search "ComfyUI_Viewer". Good news from the horse's mouth: the pack's requirements.txt literally reads "No additional dependencies required." No model downloads, no PyAV, nothing. All the heavy lifting (Prism.js, KaTeX, Mermaid) is bundled JS, not Python.

Common issues

The README's own troubleshooting is honest and short. If content isn't updating, the upstream node probably hasn't executed - run the queue, or disconnect and reconnect the input. If a view isn't detecting your content, open the browser console (F12) and look for [WAS Viewer] log lines, then check what your content actually looks like - a JSON string that isn't valid JSON falls back to plain Text. One real-world caution: this is a frontend-heavy extension, and ComfyUI's Nodes 2.0 rewrite has historically been rough on packs that ship custom frontend widgets. If you're on the new canvas and the viewer renders wrong, that's the first suspect. It's still the best way to actually see what your nodes are producing.

CategoryWAS Suite/View

Inputs (6)

NameTypeDefaultDescription
contentopt*Whatever should be displayed. Text, a list of strings, a parsed object or an image batch all work: the view that recognises the content is the one that draws it. A list arrives as one numbered container per item, each with its own tick box and copy button.
manual_contentoptSTRINGWhat was typed into the node with the Edit button. Written by the viewer rather than by hand, and saved with the workflow, so an edit survives a reload and takes precedence over the wired content.
viewer_metaoptSTRING{"lastInputHash": "", "excluded": []}Which list items are unticked, as JSON. Written by the viewer; unticked items are shown but left out of the output.
view_stateoptSTRING{}Which view is selected and anything that view has stored, as JSON. Written by the viewer, and what lets a composited canvas or a rendered frame survive a reload without re-running the graph.
hold_for_editoptBOOLEANfalse`false` shows the content and carries on. `true` stops the run here until Continue is pressed, and sends on whatever was edited. Set from Pause Workflow on the viewer's own bar.
hold_timeoutoptFLOAT6000–86400Seconds to wait before carrying on with what arrived. 600 is ten minutes, 0 waits with no limit. The whole queue holds still.

Outputs (1)

NameTypeDescription
content*What is on display, as a list. Edits replace the wired content, and unticked list items are dropped, so this is what was shown rather than what arrived.