Appearance
Unified Container Pattern
Idea from block grouping work (July 2026). Extends the Conversation V2 direction to all container-like blocks.
Observation
Today we have three container-like blocks that each store sub-blocks as properties on the parent object: Form, Slider, and Conversation. Each has its own reordering logic, its own sub-block management, and its own quirks. Block Groups, added later, use a different and simpler pattern: children are separate entries in creativeBlocks with a parent reference back to the group.
The group pattern is better:
- Reordering works the same way as top-level blocks (fractional indexing on
order) - No special-case code for "sub-blocks stored as object properties"
- Undo/redo, copy/paste, duplicate all work without per-container-type handling
- Blocks can be moved in and out of containers with just a
parentfield change - Nesting works naturally (groups inside groups)
The idea
Make the group pattern the universal container mechanism. Conversation, Form, and Slider become specialized groups rather than fundamentally different block types:
| Block | What it really is |
|---|---|
| Form | Group with allowedSubBlocks: [formInput, submitButton, text, graphic] + form-specific config (submit action, validation, success message) |
| Conversation | Group that controls flow progression + chat styling (message/choice/response properties) |
| Slider | Group with slide navigation + transition config |
| Block Group | Generic group, no specialized behavior |
Each keeps its unique configuration (form submission, flow progression, slide transitions) but the child-block storage, ordering, copy/paste, undo, and nesting all use the same code path.
What this enables
- Mixed content in conversations: Put a Graphic inside a Conversation and position it relative to the chat. Today this is impossible because Conversation is a closed system.
- Forms with arbitrary content: Add a Text block between form inputs for instructions, or a Graphic for branding, without hacking it with custom CSS.
- Nesting: A Conversation inside a Group, so its position is locked relative to other elements. Or a Form inside a Slider slide.
- Simpler codebase: One reordering system, one copy/paste system, one undo system. Today each container type has its own version of these.
Migration path
This doesn't need to happen all at once. The Conversation V2 plan already moves in this direction with FlowGroup and MessageHolderV2. A possible sequence:
- Conversation V2 (already planned) -- new rendering layer, keeps existing data model but adds flow-group concept
- Form migration -- move form inputs from parent-object properties to separate
creativeBlocksentries withparent: 'formProperties'. Form reordering is the most fragile today, so this has the highest payoff. - Slider migration -- same treatment for slider slides
- Unify -- extract shared container logic (allowedSubBlocks, child management) into a common system
Each step is backward-compatible: a containerVersion flag (like conversationVersion) gates the new behavior, and existing creatives keep working on the old path.
Related
conversation-v2-plan.md-- V2 rendering layer (Chunk 1-5)feasibility.md-- Problem analysis for conversation specifically../../BlockGrouping/progress.md-- Block grouping implementation notes