Control Visibility with Condition Blocks

View as Markdown
Last updated July 17, 2026

A Condition Block lets you switch designs based on the current item's type. It is used inside a Repeater when the items the Repeater iterates are heterogeneous, most often:

  • A Modular Block list where each block has a different schema (e.g. hero, quote, cta)
  • A Reference field that points to multiple content types (e.g. product, event, article)

Think of it as a switch statement inside the canvas: depending on what kind of thing the current iteration is, show this design or that design.

When to Use a Condition Block

You have…Reach for a Condition Block?
A Modular Block field with multiple block types (each block has a different schema)Yes
A multi-type Reference field pointing to several content typesYes
A list that needs different designs based on a discriminator fieldYes
A homogeneous list where every item has the same shapeNo: just put a single component inside the Repeater
Hide/show based on a non-discriminator booleanNo: use a regular component's visibility prop instead

If the data is "different things in the same list, each rendered its own way" → Condition Block. If the data is "same shape every time" → just a component inside the Repeater is enough.

How It Works

You'll find the Condition Block tile in the Smart Containers palette category, alongside Repeater and Section Slot. Nest it inside a Repeater for most use cases:

  1. Drop a Repeater on the canvas and bind its source (e.g. template.body_blocks for a Modular Block field, or template.recommendations for a multi-type reference).
  2. Inside the Repeater, drop a Condition Block.
  3. Select the Condition Block via the Layers tab (not by clicking the canvas; see below).
  4. In the right panel, set the When Condition (the dropdown lists the discriminators available in the iteration scope: block type names for Modular Blocks, content type UIDs for References).
  5. Inside the Condition Block, design what should render when the condition is true.

Repeat: add more Condition Blocks inside the Repeater, one per case.

Selecting a Condition Block: use the Layers tab, not the canvas

Same caveat as Repeaters: a Condition Block renders as <div style="display: contents">: an invisible wrapper. Clicking on the canvas where the Condition Block "is" selects the child inside it, not the Condition Block itself.

Click to enlarge

To select a Condition Block, switch the left panel to the Layers tab and click the Condition Block's row there. Only then does the right panel show its When Condition builder. This is the only way to set or change a Condition Block's discriminator after it's been dropped.

The Layers tree exposes the Condition Block's nested structure: the Condition Block itself, with a child Contents row (the slot inside the block that holds whatever should render when the condition is true). Both rows are reachable only through Layers: the Condition Block row to set the When Condition, the Contents row to drop the actual design that renders when the condition matches.

The right panel: When and Preview Mode

When the Condition Block is selected (via Layers), the right panel has a Configuration group with two controls:

Preview Mode: same toggle as a Repeater:

  • Off (default): the Condition Block's children render on the canvas regardless of whether the condition matches the current iteration. This lets you author the design without losing it whenever the previewed entry doesn't satisfy the condition.
  • On: the Condition Block evaluates its condition against the current iteration item and renders children only when truthy. Use this to verify the conditional really fires the way you intended before deploying.

This is purely an authoring aid; deployed rendering always evaluates the condition.

When Condition: three picks:

PartWhat you choose
Field to testA field on the current iteration item. Studio shows fields available on whatever the parent Repeater is iterating: block type for Modular Blocks, _content_type_uid for References, any field for Group lists.
OperatorHow to compare. Studio offers different operators depending on the field's data type (see below).
ValueWhat to compare against. Free-form for strings/numbers; dropdown for enums and known options (block type names, content type names, booleans).

Operators available per field type

The operator dropdown adapts to what kind of field you picked:

If the field is a…The operators offered are
Single-line text / URL / multi-line textequals, not equals, contains, does not contain, starts with, ends with, matches (regex), is empty, is not empty
Numberequals, not equals, less than, less than or equal, greater than, greater than or equal
Booleanis true, is false
Datebefore, after, equals (with date and relative-date pickers)
Select / Choice (single or multi)is one of, is none of
Group with multiple / listis empty, is not empty, length equals, contains an item with a given field value
Referencecontent type is, content type is not
Modular Blockis of type, is not of type
File / Imagehas value, is empty

How Studio decides whether to render

For each item the Repeater produces, Studio walks the Condition Blocks in the order they're listed in Layers. For each one:

  • Matches → the Condition Block's children render. The next Condition Block is still checked; both can match.
  • Doesn't match → the Condition Block renders nothing for this iteration. Move on.

Two Condition Blocks can both match the same iteration. They're independent guards, not a switch with break, both render if both match. If you want exclusive behaviour ("if hero, render hero design; otherwise render fallback"), make the conditions disjoint.

Bindings inside a Condition Block

Inside a Condition Block that sits inside a Repeater, repeater.* (picker root: "Repeater Data") refers to the current iteration item that matched the condition. So if the condition is block is of type hero, repeater.headline inside that Condition Block refers to the matched hero block's headline. The SDK encodes these as RepeaterBindingValue with a repeaterUID, distinct from template-level TemplateBindingValue.

  • For Modular Blocks: the blocks union narrows to just the matched type inside the Condition Block, so repeater.* autocompletes the matched block's fields.
  • For References: the referenced content type is known inside the Condition Block, so repeater.* autocompletes the referenced CT's fields.

Inside a Repeater Iterating Modular Blocks

A blog_post content type has a body_blocks field: a Modular Block list where each block can be one of hero, feature_grid, quote, or cta. Each block type has its own schema.

Click to enlarge

At render time, the Repeater iterates body_blocks. For each block:

  • A hero block matches the first Condition Block → renders the Hero.
  • A feature_grid block matches the second → renders the feature grid.
  • And so on for each block type.

One composition, four different designs, one Repeater + four Condition Blocks. Authors add blocks in any order and repeat block types; Studio renders each one correctly.

See Modular Blocks for how the underlying field is modelled and how the blocks union is exposed to Studio.

Inside a Repeater Iterating Reference Fields

A recommendations field on blog_post is a Reference field that points to entries from multiple content types: product, event, article. You want each kind rendered with its own card design.

Click to enlarge

Same idea, the Repeater iterates the reference list; each iteration is a different content type; each Condition Block matches its type and renders the appropriate design. The discriminator under the hood is _content_type_uid on the referenced entry, exposed in the picker as "content type is".

See References for how multi-type reference fields are modelled.

Standalone Use (Rare)

Condition Blocks are almost always nested inside a Repeater, because that's where heterogeneity naturally appears. But a Condition Block can sit at the template level too, directly inside a section or template, not inside a Repeater. In that case the discriminator is a field on the template/entry itself, not on a per-item iteration.

Common standalone uses:

  • Audience / variant switch: Condition Block on template.audience to render a different design when the entry is targeted at a specific audience (when not using the platform's Personalize feature directly).
  • Feature flag: Condition Block on a boolean like template.show_promo to gate an entire section.
  • Stage gating: Condition Block on template.status to render preview-only scaffolding when the entry is in draft.

For these standalone cases the repeater.* root doesn't apply; bindings inside the Condition Block come from template.* as usual.

Multiple Condition Blocks for One Type (Allowed but Rare)

You can have two Condition Blocks both matching the same block type, useful for things like "show this hero design for entries with featured: true, and that hero design otherwise". Both render if both match (they are independent guards, not switch/break).

For simple "true/false" splits this works. For richer conditional logic, consider modelling it as separate block types instead.

Condition Blocks vs. Section Slots

Both let the page vary based on data, but in different ways:

NeedCondition BlockSection Slot
Different designs per item type in a listYesSlots don't switch on data
Different content per page instanceConditions don't switch on pageYes
Fixed structure, dynamic contentYesSlots leave content open
Author-chosen component variationsConditions are data-drivenYes: slots are author-chosen

Use Conditions for data-driven branching; use Slots for author-driven flexibility.

Common Pitfalls

SymptomCauseFix
Condition Block doesn't render anythingCondition never matches the current iterationCheck the discriminator, for Modular Blocks, confirm the block type UID matches; for References, confirm the entry's CT UID matches
Two Condition Blocks for the same type both renderThey're independent guards, not exclusive casesMake one condition more specific, or accept both rendering and order them intentionally (most-specific condition first)
Binding inside a Condition Block doesn't resolveThe condition narrowed to a type that doesn't have that fieldOnly fields on the matched block / entry type are available inside the Condition Block. Verify the field exists on that type.
Adding a new Modular Block type doesn't render anythingNo Condition Block matches the new typeAdd a Condition Block for the new type, or a fallback Condition Block at the end that catches anything unmatched

See Also

  • Repeaters: the sibling pattern; Condition Blocks almost always live inside one
  • Modular Blocks: the most common heterogeneous source
  • References: multi-type reference fields are the other common heterogeneous source
  • Section Slots: author-driven content variation (the contrast above)