A Practitioner's Guide to Handlebars in Iterable
Stop banging your head against a wall of Handlebars confusion.
If you’re an Iterabler user, then you’ve definitely heard of Handlebars. Handlebars is Iterable’s chosen “templating language” — a code structure that allows you to create dynamic content, messages, segments, and can actually simplify complex email builds with repetitive modules.
That said, all templating languages have their quirks. Whether it’s Iterable Handlebars, Braze’s Liquid (don’t confuse it with Shopify’s Liquid), Customer.io’s Liquid (yes, it’s different), Hubspot’s HubL, or Klaviyo’s Django, there’s always a steep learning curve when you’re trying to use it in practice.
This is the Handlebars guide we wish existed when we started working with it. Hopefully, this guide helps you avoid some of the hair loss and head-banging that so many people go through when trying to implement it in their messaging.
The “Basics”
Handlebars is a known templating language that existed well before Iterable. Other platforms, like Sendgrid, use it to populate dynamic content in messaging. That said, each platform that uses “Handlebars” has adapted it in special ways that are unique to its platform.
That’s why when you try to search for help on Handlebars, or run an idea through AI, you often get answers that are incomplete, or worse: incorrect. AI and web search discover solutions using the master knowledge base of Handlebars — not Iterable handlebars specifically.
defaultIfEmpty — Your First Line of Defense
This is the helper you’ll use more than any other. It provides a fallback value when a user profile field is blank or missing:
{{defaultIfEmpty firstName "there"}}
{{defaultIfEmpty preferredLocation "you"}}
{{defaultIfEmpty hotel.imgUrl "<https://fallback.example.com/hero.jpg>"}}
We use defaultIfEmpty on virtually every personalized field. The alternative is broken personalization — “Hey {blank}, check out our latest...” — and that erodes trust faster than no personalization at all.
Here are some field examples we protect most often: firstName, preferredLocation, heading or subheading (these are technically #assign variables, but don’t sweat that for now), hotel.url, imageUrl, etc.
If it’s user-facing and dynamic, it gets a fallback.
Date Formatting with {{now}}
Dynamic dates in Iterable use the now helper with Java date format strings:
{{now format='yyyy'}}This returns the current year — useful for copyright footers that you never want to manually update again.
{{#each}} Loops Patterns
Loops are where Handlebars in Iterable gets genuinely powerful — and genuinely tricky. The {{#each}} helper allows you to “iterate” or repeat content, code, and data fields for customer data that comes to you in a list-like format (a.k.a. “Arrays”). Below are some of the most common #each loops we see:
Cart Recovery URLs
{{#each shoppingCartItems}}
{{#unless @first}},{{/unless}}
{{this.url}}
{{/each}}
The {{#unless @first}} conditional prevents a leading comma on the first item. Useful when constructing comma-delimited strings for cart recovery links.
Shopping Cart Item Arrays
For abandoned cart emails, shoppingCartItems is an array on the user profile:
{{#each shoppingCartItems}}
<img src="{{imageUrl}}" alt="{{name}}" />
<p>{{name}} — {{color}}, Size {{size}}</p>
{{/each}}Collection Loops
{{#each collection}}
{{#ifContainsStr (replace searchTerm " " "") this.category}}
<!-- render this item -->
{{/ifContainsStr}}
{{/each}}This pattern filters collection items based on a search term, with a replace helper to strip whitespace.
Conditional Helpers Beyond {{#if}}
Iterable extends standard Handlebars with custom conditional helpers:
{{#ifEq}} — Exact Match
{{#ifEq teamSport targetSport}}
<!-- show sport-specific content -->
{{/ifEq}}{{#ifContainsStr}} — Partial Match
{{#ifContainsStr userCategories "running"}}
<!-- show "running" content -->
{{/ifContainsStr}}{{#assign}} — Template-Level Variables
{{#assign "primaryColor" "#FF6B35"}}
Variables set with #assign are available throughout the template. We use these for brand colors, repeated copy, and — importantly — as a workaround for snippet variable limitations.
The Snippet Variable Limitation (And the Workaround)
This catches every team eventually: snippets in Iterable cannot parse Handlebars the way templates can.
The workaround:
Store dynamic copy in
{{#assign}}variables at the top of the email templatePass those variables through to the snippet using snippet variable references
The snippet receives the resolved value, not the Handlebars expression
<!-- In the template -->
{{#assign "disclaimer_text" (defaultIfEmpty disclaimerCopy "Standard terms apply.")}}
<!-- In the snippet, reference the variable -->
{{disclaimer_text}}
This is an architectural decision you make once and bake into your snippet registry.
The {{join}} Helper for Arrays
When you need to display an array as a formatted string:
{{join tags ", "}}
Renders ["running", "yoga", "cycling"] as “running, yoga, cycling.”
Data Feeds: Same Helpers, New Source
Data feeds let you pull external JSON into your template — from your own API, a CMS, a recommendation service, or the pattern we use most often, Airtable. That Airtable approach turns one blast into infinite personalized sends without cloning templates — it’s the single biggest leverage point most lifecycle teams are missing.
That said, from a Handlebars perspective, feed data is just another data source. Every helper you’ve already learned applies:
{{#each feedItems}}
<h3>{{defaultIfEmpty this.title “Untitled”}}</h3>
<p>{{this.description}}</p>
{{/each}}The one Handlebars-specific gotcha: if no rows match your filter criteria, Iterable defaults to the first row. A user who should see nothing sees whatever’s at the top of your feed instead. Guard with {{#if}}.
{{#if partner}}
<!-- feed-driven content -->
{{/if}}
When to Get External Help
Handlebars can be a lot to keep track of. It can power your messages, snippets, subject lines, segments, and more. If this all feels like “too much, too soon” — consider chatting with us at Modular. We have a proven track record of creating dynamic solutions with Handlebars that directly affects bottom-line metrics (check out this case study), and we’d love to help you.


