textconcatenate
Concatenate up to 50 strings, because ComfyUI makes you build prompts in pieces
- text
ComfyUI has no built-in "join these strings together" node, which is absurd given how often you need one. The moment you start building prompts modularly - a fixed subject string here, a style string from a wildcard node there, a quality block from somewhere else - you're either juggling nodes or typing the whole thing into one box. textconcatenate is the glue: take up to 50 text inputs, join them with a separator, hand you back one clean string.
The author's own comment in the source says it's a rework of the classic WAS Node Suite's Text Concatenate, so you're getting a well-trodden design with a slightly friendlier face. It's the natural companion to the pack's wildcard nodes: makiwildcards gives you a random scene fragment, makitextwildcards gives you a random line, and this stitches everything - plus your fixed text - into a single prompt string for a CLIP Text Encode.
How it works
The node has a text_count dial (1–50). Set it to 4 and you get four text fields, set it to 8 and you get eight - the unused fields hide themselves via the pack's frontend script, so you're not staring at 49 empty boxes. On run, it takes the active text inputs in order, drops any that are empty, optionally strips leading/trailing whitespace, optionally turns underscores into spaces, and joins the survivors with your delimiter.
Two details worth knowing. First, empty strings are silently skipped, so text_count can be generous and the node just concatenates whatever is actually filled. Second, if you put \n in the delimiter field it becomes a newline - handy for line-break-separated prompts or negative-prompt blocks, and the same trick the wildcard nodes use.
Inputs and outputs
- text_count - how many text slots are active (default 3).
- text_1 … text_N - the strings to join.
- delimiter - separator between texts, default
", ". - clean_whitespace - strip the ends of each input (default on).
- replace_underscore - turn
_into spaces (default on). This one earns its keep on danbooru-style tag lists where the model readslong_hairandlong hairdifferently.
Output is a single text string. Feed it into a positive prompt or negative prompt encode - for negatives it's especially nice, since a shared bad quality, blurry, watermark block can live in one input you reuse across workflows.
Installation
Part of the ComfyUI-Prompt-Wildcards pack. ComfyUI Manager: search "ComfyUI-Prompt-Wildcards". Or:
cd ComfyUI/custom_nodes
git clone https://github.com/MakkiShizu/ComfyUI-Prompt-Wildcards.git
Restart ComfyUI. No extra Python packages, no model files.
Common issues
- Changing
text_countdoesn't show new fields. The show/hide is handled by the pack's JS. If you're on a fresh install, make sure you fully reload the frontend (hard refresh in the browser) after restarting ComfyUI so the extension registers. - Output has double separators. Check
clean_whitespace. If a text input ends with a space and you also have a delimiter, you can getthing, , thing. The default cleaning usually prevents this; a pasted input with trailing spaces is the usual culprit. - Underscores you wanted to keep get replaced. That's what
replace_underscoredoes - flip it off if you're joining text where_is meaningful.
It won't win any prizes for excitement, but it's the kind of node that quietly unblocks a dozen workflows. If you'd rather not count slots at all, the same pack's textconcatenate_v2 grows its inputs as you connect them - no text_count to think about.
Inputs (53)
| Name | Type | Default | Description |
|---|---|---|---|
| text_count | INT | 31–50 | — |
| delimiter | STRING | , | — |
| clean_whitespace | BOOLEAN | true | — |
| replace_underscore | BOOLEAN | true | — |
| text_1 | STRING | — | |
| text_2 | STRING | — | |
| text_3 | STRING | — | |
| text_4 | STRING | — | |
| text_5 | STRING | — | |
| text_6 | STRING | — | |
| text_7 | STRING | — | |
| text_8 | STRING | — | |
| text_9 | STRING | — | |
| text_10 | STRING | — | |
| text_11 | STRING | — | |
| text_12 | STRING | — | |
| text_13 | STRING | — | |
| text_14 | STRING | — | |
| text_15 | STRING | — | |
| text_16 | STRING | — | |
| text_17 | STRING | — | |
| text_18 | STRING | — | |
| text_19 | STRING | — | |
| text_20 | STRING | — | |
| text_21 | STRING | — | |
| text_22 | STRING | — | |
| text_23 | STRING | — | |
| text_24 | STRING | — | |
| text_25 | STRING | — | |
| text_26 | STRING | — | |
| text_27 | STRING | — | |
| text_28 | STRING | — | |
| text_29 | STRING | — | |
| text_30 | STRING | — | |
| text_31 | STRING | — | |
| text_32 | STRING | — | |
| text_33 | STRING | — | |
| text_34 | STRING | — | |
| text_35 | STRING | — | |
| text_36 | STRING | — | |
| text_37 | STRING | — | |
| text_38 | STRING | — | |
| text_39 | STRING | — | |
| text_40 | STRING | — | |
| text_41 | STRING | — | |
| text_42 | STRING | — | |
| text_43 | STRING | — | |
| text_44 | STRING | — | |
| text_45 | STRING | — | |
| text_46 | STRING | — | |
| text_47 | STRING | — | |
| text_48 | STRING | — | |
| text_49 | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |