Optional String Join (3)
Subject, style, and scene — Optional String Join (3)
- text
Three inputs is the sweet spot for a lot of prompt work. One slot for the subject, one for style or quality tags, one for lighting or environment - and Optional String Join (3) from the String Join Tools pack stitches them together without ever leaving you with a double separator.
Like its two-input sibling, every text socket here is optional. Unconnected inputs are skipped, and so are inputs that arrive as an exact empty string. Whitespace-only strings are kept, embedded line breaks survive, and the separator is inserted only between usable strings. If all three are empty or missing you get "" - which is exactly what you want flowing into a CLIP encoder, because an empty positive prompt is a far saner failure than ", , ".
The three-part prompt shape
The classic setup: text_1 holds the subject ("a young woman in a raincoat"), text_2 holds a style or quality block you can mute at will, and text_3 holds the scene or lighting. Wire all three to this node and the single text output into CLIP Text Encode, and you've got one tidy place to audition combinations.
Where the optionality earns its keep is when one of the three branches is conditional. Say your style block comes from a wildcard-style picker that occasionally returns nothing. A naive concatenator would glue the empty string in and give you a doubled separator. This node just drops the empty slot, so the prompt stays clean whether two or all three inputs are live. That's the behavior the pack is built around, and it's why people reach for it over hand-rolling a concat.
What you actually set
separator- the one widget, default", ". Supports escapes:\nfor a newline,\r\nfor CRLF,\tfor a tab,\\for a backslash. Anything unsupported is kept literally.text_1,text_2,text_3- optionalSTRINGsockets, wire-only. Feed them from other string-producing nodes; you can't type into them.- Output:
text, a singleSTRING, ready for a text encoder, a saver's metadata, or another join node.
The mechanism is the same small, boring logic as the rest of the family: filter out missing and empty strings, decode the separator, join in socket order. No state, no server calls, nothing to go wrong. It's plumbing, and it's supposed to be.
Installing it
Via ComfyUI Manager, search "String Join Tools" or "ComfyUI-StringJoinTools" and install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ruminar/ComfyUI-StringJoinTools
Restart ComfyUI and refresh the browser. The pack ships with no Python dependencies and downloads no models, so this is a thirty-second install either way. You'll find the node under String Join Tools.
One thing to remember
The inputs are sockets, not boxes. If you want a fixed string in one slot, drop a PrimitiveString (or any text source) and wire it in - that's also how you keep a subject in sync across several joins without retyping it. And if three slots ever feels cramped, the pack's (5) and (10) variants, or chaining joins in stages, cover you without learning anything new.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| separator | STRING | , | Inserted only between usable strings. Supports \n, \r\n, \t, and \\. |
| text_1opt | STRING | Optional STRING input. Missing inputs and exact empty strings are ignored. | |
| text_2opt | STRING | Optional STRING input. Missing inputs and exact empty strings are ignored. | |
| text_3opt | STRING | Optional STRING input. Missing inputs and exact empty strings are ignored. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |