Skip to content

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 parent field 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:

BlockWhat it really is
FormGroup with allowedSubBlocks: [formInput, submitButton, text, graphic] + form-specific config (submit action, validation, success message)
ConversationGroup that controls flow progression + chat styling (message/choice/response properties)
SliderGroup with slide navigation + transition config
Block GroupGeneric 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:

  1. Conversation V2 (already planned) -- new rendering layer, keeps existing data model but adds flow-group concept
  2. Form migration -- move form inputs from parent-object properties to separate creativeBlocks entries with parent: 'formProperties'. Form reordering is the most fragile today, so this has the highest payoff.
  3. Slider migration -- same treatment for slider slides
  4. 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.

  • conversation-v2-plan.md -- V2 rendering layer (Chunk 1-5)
  • feasibility.md -- Problem analysis for conversation specifically
  • ../../BlockGrouping/progress.md -- Block grouping implementation notes

Internal documentation