Overview
Courier Elemental supports four control flow properties that enable dynamic, data-driven notification templates:if- Conditionally render elements based on data or conditionsloop- Repeat elements for each item in an arrayref- Reference elements to check their visibility or propertieschannels- Show elements only on specific channels
Control flow properties are evaluated at render time using Handlebars expressions. You can access data from
message.data, message.to.data, and other message context.If
Theif property conditionally renders an element based on a Handlebars expression. If the expression evaluates to a truthy value, the element is rendered; otherwise, it’s skipped.
When to use:
- Show different content based on user type, subscription status, or feature flags
- Display elements only when certain data exists
- Create personalized experiences based on user context
- Hide elements that aren’t relevant to the current recipient
Basic Example
Realistic Examples
Conditional welcome message based on user type:Ref
Theref property names an element so it can be referenced by other elements. Referenced elements provide access to their properties and a visible property that indicates whether the element was rendered.
When to use:
- Check if another element was rendered before showing related content
- Create dependencies between elements
- Build complex conditional logic based on element visibility
- Access element properties from other elements
Basic Example
Realistic Example
Show follow-up content only if initial element is visible:Loop
Theloop property renders an element multiple times, once for each item in an iterable data source (typically an array).
When to use:
- Display lists of products, orders, notifications, or other array data
- Create dynamic content that adapts to variable-length data
- Build repeating patterns like product cards or notification items
- Iterate over nested data structures
$.item- The current item in the iteration$.index- The zero-based index of the current iteration
Basic Example
Realistic Examples
Product list with nested data:$.index for item numbering:
Channels
Thechannels property selectively renders an element based on the current notification channel. This allows you to show different content for email, SMS, push, and other channels.
When to use:
- Show detailed content in email, concise content in SMS
- Display channel-specific formatting or elements
- Customize content per channel while maintaining a single template
- Hide elements that don’t work well on certain channels
email, push, direct_message, sms, or provider-specific channels like slack, discord, etc.
For more advanced channel customization, you can also use Channel elements to define completely different content structures per channel.
Basic Example
Realistic Examples
Channel-specific content:Combining Control Flow Properties
You can combine multiple control flow properties on the same element:channels- Element must match current channelif- Condition must evaluate to truthyloop- Element is repeated for each item (if present)ref- Element is registered for reference (if present)
Best Practices
- Use
iffor conditional content: Show/hide elements based on data or user context - Use
loopwithgroup: Wrap looped elements in a group for better organization - Reference order matters: Elements must be defined before they’re referenced
- Test with real data: Control flow expressions are evaluated at render time, so test with realistic data structures
- Combine with locales: Use control flow with localization for fully dynamic, multi-language notifications
- Channel considerations: Remember that some elements (like columns) may not render well on all channels