substitution_data, and the block automatically generates one copy per item at send time.
This is different from the {{each}} syntax in the Template Language, which operates at the code level inside raw HTML. Loop Blocks give you the same looping capability through a drag-and-drop interface, so you can build dynamic, data-driven layouts without writing template code.
What Are Loop Blocks?
A Loop Block is a special content block in the Topol email editor that repeats its content for each item in an array. You design the layout of a single item—an image, text, price, button, or any combination of content blocks—and the Loop Block renders that layout once per entry in the connected data array. At send time, Lettr reads the array from yoursubstitution_data and expands the Loop Block into the appropriate number of copies, each populated with the corresponding item’s values.
How It Works
- You insert a Loop Block in the visual editor
- You link it to a Loop Merge Tag that defines the available fields (name, image, price, etc.)
- You design the layout using those fields as placeholders
- At send time, Lettr iterates over the array and renders one copy of the block per item
Loop Blocks vs Template Language Loops
Lettr provides two ways to render repeating content. Choose based on your workflow and the complexity of the layout.| Aspect | Loop Blocks | {{each}} Syntax |
|---|---|---|
| Editing interface | Visual drag-and-drop editor | Raw HTML / template code |
| Design control | Structure and block settings panels | Full HTML and CSS control |
| Requires code knowledge | No | Yes |
| Best for | Designers building visual templates | Developers writing HTML templates |
| Nesting support | Single level | Multiple levels via loop_vars |
| Where it lives | Topol editor canvas | Template HTML source |
| Responsive behavior | Handled automatically by the editor | Manual responsive implementation |
When to Use Loop Blocks
- You’re building templates in the visual editor and want repeating sections without writing code
- The repeating layout follows a standard pattern (image + text + button cards, product grids, lists)
- Non-technical team members need to create and maintain templates with dynamic lists
When to Use {{each}} Syntax
- You need nested loops (e.g., categories containing products)
- You’re working in custom HTML blocks or raw HTML templates
- You need fine-grained control over the generated markup
- You want to use
loop_indexfor conditional formatting (e.g., alternating row colors)
Loop Blocks and
{{each}} syntax can coexist in the same template. Use Loop Blocks for the visual sections and {{each}} for any custom HTML blocks that need more control.Creating a Loop Block
Open the Content Blocks Panel
In the Topol editor, open the content blocks panel on the left side of the editor.
Insert a Loop Block
Drag the Loop Block element onto your template canvas. It appears as a repeatable section with a loop indicator.
Link to a Loop Merge Tag
In the block’s properties panel, select a Loop Merge Tag from the dropdown. This determines which array in your
substitution_data provides the data and which fields are available inside the block.Design the Item Layout
Add content blocks inside the Loop Block—text, images, buttons, or any standard block. Use the merge tag fields from your Loop Merge Tag to insert dynamic values.
Configuring Loop Block Data Sources
Loop Blocks are powered by Loop Merge Tags, which define the data structure the block expects. Each Loop Merge Tag maps to an array in yoursubstitution_data and declares the fields available for each item.
Merge Tag Configuration
Loop Merge Tags are configured in your team’s Editor Settings page (under the merge tags section). Each Loop Merge Tag is a standard merge tag item that includes achildrenProperties array listing the fields available inside the loop:
value (the merge tag placeholder), text (display name), label (description), and type (controls how the editor renders the field). Child merge tag keys are independent identifiers—they do not need to include the parent key name.
Lettr creates new teams with a default Loop Blocks merge tag group containing an “Invoice Items” loop (
{{INVOICE_ITEMS}}) with children for item name, description, quantity, unit price, and total. You can customize these defaults or add your own loop merge tags in Editor Settings.Supported Field Types
| Type | Description | Usage |
|---|---|---|
text | Plain text value | Product names, descriptions, prices |
image | Image URL | Product photos, avatars, icons |
button | Link URL | Call-to-action buttons, product links |
number | Numeric value | Quantities, ratings, counts |
Providing Data at Send Time
Thesubstitution_data structure must include an array whose key matches the Loop Merge Tag value (without the braces). Each array element is an object whose keys match the child merge tag values (also without braces):
PRODUCTS array.
Designing Loop Block Content
Inside a Loop Block, you can use any standard content block from the editor. The merge tag fields from your Loop Merge Tag are available as placeholders in each block’s settings.What You Can Place Inside a Loop Block
- Text blocks: Display product names, descriptions, prices, or any text field
- Image blocks: Show product photos, avatars, or icons using image-type fields
- Button blocks: Create call-to-action buttons using button-type fields for the URL
- Divider and spacer blocks: Separate items visually
- Structures with columns: Create multi-column layouts within each loop iteration (e.g., image on the left, details on the right)
Combining Loop Blocks with Standard Merge Tags
Loop Blocks and standard merge tags work together in the same template. Standard merge tags handle single values (recipient name, order number), while Loop Blocks handle arrays (product lists, line items).{{CUSTOMER_NAME}},{{ORDER_ID}}, and{{ORDER_TOTAL}}render as standard merge tags in text blocks- The
PRODUCTSarray drives the Loop Block, rendering three product cards
Comparison: Same Output, Two Approaches
Here’s how you would render an order items list using each method.Using a Loop Block (Visual Editor)
In the Topol editor, you would:- Insert a Loop Block
- Link it to a
PRODUCTSLoop Merge Tag - Design a two-column structure: image on the left, name and price on the right
- Add a button block with the product URL
Using {{each}} Syntax (Template Code)
{{each}} approach gives you full HTML control and supports nested loops.
Best Practices
Data Structure
- Keep array items consistent: Every object in the array should have the same fields. Missing fields render as empty values.
- Use descriptive field names:
PRODUCT_NAMEis clearer thanNwhen configuring merge tags and debugging. - Provide fallback content: If an array might be empty, use a conditional block around the Loop Block area to show a fallback message.
Design
- Design for variable length: Your layout should look good with 1 item and with 10 items. Test with different array sizes.
- Keep item layouts compact: Each loop iteration adds height to the email. Avoid overly tall item cards that make the email scroll excessively.
- Test on mobile: Multi-column layouts inside Loop Blocks stack on mobile. Verify the stacking order looks correct with real data.
Performance
- Limit array size: Very large arrays (50+ items) increase email size and rendering time. For long lists, consider linking to a web page instead.
- Optimize images: Use appropriately sized images in Loop Blocks. High-resolution images repeated many times significantly increase email weight.
Troubleshooting
Loop Block renders nothing
Loop Block renders nothing
Confirm that the
substitution_data includes the array key matching the Loop Merge Tag value. Check that the array is not empty and that each object contains the expected fields.Fields show as blank inside the loop
Fields show as blank inside the loop
Verify that the field names in your
substitution_data objects match the childrenProperties defined in the Loop Merge Tag. Field names are case-sensitive.Loop Block not available in the editor
Loop Block not available in the editor
Loop Blocks require Loop Merge Tags to be configured in the editor settings. Ensure your editor configuration includes at least one merge tag with a
childrenProperties array.Layout breaks with many items
Layout breaks with many items
Large arrays can produce very long emails. Consider paginating your data or limiting the array to a reasonable number of items (typically under 20) and linking to a full list on the web.