Loops: iterate over data in your components
BetaThis feature is new and we're actively working to improve it. UpdatedIn Design Studio, components support loops, enabling you to iterate with fewer keystrokes.
Use our Design Studio GPT to create a custom component!
Learn how to best utilize our GPT to create code for reusable, custom content.
Loop through numbers
Numerical iteration is 0 indexed - the first number is 0.
<template>
<ul>
<li #each="n in 10">${n}</li>
</ul>
</template>
Using this component in an email:
<html>
<body>
A simple email
<my-first-component></my-first-component>
</body>
</html>
The output source becomes:
<html>
<body>
A simple email
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</body>
</html>
Loop through arrays
You can loop through an array to dynamically generate repeated elements—like list items—based on your data.
<template>
<ul>
<li
#each="food in ['tomato','potato','lettuce', 'cucumber', 'carrots','apples']"
>
${food}
</li>
</ul>
</template>
Using this component in an email:
<html>
<body>
A simple email
<my-first-component></my-first-component>
</body>
</html>
The output source becomes:
<html>
<body>
A simple email
<ul>
<li>tomato</li>
<li>potato</li>
<li>lettuce</li>
<li>cucumber</li>
<li>carrots</li>
<li>apples</li>
</ul>
</body>
</html>
Passing in arrays
You can also pass in arrays to a component to render data defined in each email they’re in.
<script>
export const props = Component.defineProps({
products: {
schema: Component.props.array(Component.props.string()),
},
});
</script>
<template>
<ul>
<li #each="product in products">${product}</li>
</ul>
</template>
Using this component in an email:
<html>
<body>
A simple email
<my-first-component :products="['apples','bananas','tomatoes']">
</my-first-component>
</body>
</html>
The resulting output is:
<html>
<body>
A simple email
<ul>
<li>apples</li>
<li>bananas</li>
<li>tomatoes</li>
</ul>
</body>
</html>
Passing in objects
<script>
export const props = Component.defineProps({
products: {
schema: Component.props.array(
Component.props.object({
name: Component.props.string(),
price: Component.props.string(),
})
),
},
});
</script>
<template>
<ul>
<li #each="product in props.products">${product.name} - ${product.price}</li>
</ul>
</template>
<html>
<body>
A simple email
<my-first-component :products="[
{name:'apple', price:'$0.50'},
{name:'banana', price:'$0.75'},
{name:'tomato', price:'$3.00'}
]">
</my-first-component>
</body>
</html>
The output is:
<html>
<body>
A simple email
<ul>
<li>apple - $0.50</li>
<li>banana - $0.75</li>
<li>tomato - $3.00</li>
</ul>
</body>
</html>
You can also import objects that are not iterated over.
<script>
export const props = Component.defineProps({
products: {
schema: Component.props.array(
Component.props.object({
name: Component.props.string(),
price: Component.props.string(),
})
),
},
store: {
schema: Component.props.object({
name: Component.props.string(),
location: Component.props.string(),
}),
}
});
</script>
<template>
<ul>
<li #each="product in props.products">${product.name} - ${product.price}</li>
</ul>
${props.store.name}
<br />
${props.store.location}
</template>
<html>
<body>
A simple email
<my-test :products="[
{name:'apple', price:'$0.50'},
{name:'banana', price:'$0.75'},
{name:'tomato', price:'$3.00'}
]"
:store="{
name: 'Main Office',
location: '123 Somewhere Drive'
}">
</my-test>
</body>
</html>
The output is:
<html>
<body>
A simple email Main Office
<br />
123 Somewhere Drive
</body>
</html>
Enumerated iteration
Sometimes you want access to both the iterated item and its index (count) in the loop.
<template>
<table>
<tr>
<th>Food</th>
<th>Index</th>
<th>Conditional Message</th>
</tr>
<tr
#each="(food,index) in ['tomato','potato','lettuce', 'cucumber', 'carrots','apples', 'bananas', 'beans']"
>
<td>${food}</td>
<td>${index}</td>
<td>${index>3?'the first 4 items dont get this message':''}</td>
</tr>
</table>
</template>
Using this in a simple email:
<html>
<head></head>
<body>
<h1>My shopping list</h1>
<enumerated-iteration></enumerated-iteration>
</body>
</html>
This is the output source:
<html>
<head></head>
<body>
<h1>My shopping list</h1>
<table>
<tr>
<th>Food</th>
<th>Index</th>
<th>Conditional Message</th>
</tr>
<tr>
<td>tomato</td>
<td>0</td>
<td></td>
</tr>
<tr>
<td>potato</td>
<td>1</td>
<td></td>
</tr>
<tr>
<td>lettuce</td>
<td>2</td>
<td></td>
</tr>
<tr>
<td>cucumber</td>
<td>3</td>
<td></td>
</tr>
<tr>
<td>carrots</td>
<td>4</td>
<td>the first 4 items dont get this message</td>
</tr>
<tr>
<td>apples</td>
<td>5</td>
<td>the first 4 items dont get this message</td>
</tr>
<tr>
<td>bananas</td>
<td>6</td>
<td>the first 4 items dont get this message</td>
</tr>
<tr>
<td>beans</td>
<td>7</td>
<td>the first 4 items dont get this message</td>
</tr>
</table>
</body>
</html>
Enumerated object iteration
<template>
<div
#each="(value, key, index) in {key1:'value1',key2:'value2', key3:'value3'}"
>
${index+1}. ${key}: ${value}
</div>
</template>
Using this component in a simple email:
<html>
<head></head>
<body>
<enumerated-iteration></enumerated-iteration>
</body>
</html>
The output source becomes:
<html>
<head></head>
<body>
<div>1. key1: value1</div>
<div>2. key2: value2</div>
<div>3. key3: value3</div>
</body>
</html>