Loading...
Skip to main content

Control Flow

In addition to their standard properties, Courier elements have a few additional properties that allow you to apply control flow logic to the element.

Each control flow property is optional.

If

Conditionally renders an element.

Applies to: text, meta, channel, group, action, image.

Examples

{
"type": "text",
"content": "Hello, {{first_name}} {{last_name}}",
"if": "data.some_field === 3"
}

Ref

Names an element for reference by other elements. Referenced elements provide access to:

  • Their properties
  • A visible property (true if rendered, false otherwise)

Note: An element cannot reference another before it is defined.

Applies to: text, meta, channel, group, action, image.

Example

{
"type": "text",
"content": "Hello, {{first_name}} {{last_name}}",
"ref": "el3"
},
{
"type": "text",
"content": "Hello **world**",
"if": "refs.el3.visible"
}

Loop

Renders an element multiple times based on an iterable data source.

  • loop must evaluate to an iterable data source
  • $.item refers to the current item in the iteration
  • $.index provides the current index
Incrementing Loop Index

When using $.index in loops, you can easily display a 1-based item number by using the add handlebar helper:

Item {{add $.index 1}}: {{$.item.name}}

This will output "Item 1", "Item 2", etc., instead of starting from zero.

Applies to: text, channel, group, action, image.

Example:

{
"type": "text",
"content": "* {{$.item.name}} listed at {{$.item.price}}",
"loop": "data.products"
}

Full message payload:

{
"message": {
"content": {
"version": "2022-01-01",
"elements": [
{
"type": "text",
"content": "* {{$.item.name}} listed at {{$.item.price}}",
"loop": "data.products"
}
]
},
"data": {
"products": [
{
"name": "Mouse",
"price": "$10"
},
{
"name": "Keyboard",
"price": "$20"
}
]
}
}
}

Expanded result:

{
"type": "text",
"content": "* Mouse listed at $10",
"loop": "data.products"
},
{
"type": "text",
"content": "* Keyboard listed at $20",
"loop": "data.products"
}

Channels

Selectively renders an element based on the current channel.

Valid channels: email, push, direct_message, sms, or provider channels like slack.

Applies to: text, meta, channel, group, action, image.

Example

{
"type": "text",
"content": "Hello, {{first_name}} {{last_name}}",
"channels": ["email", "slack"]
}