Using HTML Code Blocks in the Email Editor

HTML Code Blocks give you full control over your email design. Write your own HTML and CSS, pull in live product data, personalize content with dynamic fields, and loop through multiple products — all inside the email template builder.


Getting Started

  • Open the Email Template Builder
  • Add an HTML Element to your template
  • You'll see two editors:
    • HTML Content — write your HTML and template logic here
    • CSS Style — write your styles here (automatically inlined for email client compatibility)
  • Use the Dynamic Fields panel below the editors to browse all available variables

Displaying Products

Pull product data directly into your email using two built-in functions. Reference products by their store product ID (SKU).

Single Product

Use get_product_by_id('PRODUCT_ID') to fetch one product:

{% set product = get_product_by_id('SKU-123') %}

<div class="product-card">
    <img src="{{ product.image }}" alt="{{ product.name }}" />
    <h2>{{ product.name }}</h2>
    <p>{{ product.description }}</p>
    <p class="price">${{ product.price }}</p>
    <a href="{{ product.url }}">Shop Now</a>
</div>

Multiple Products

Use get_products_by_id(['ID1', 'ID2', 'ID3']) to fetch several products at once, then loop through them:

{% set products = get_products_by_id(['SKU-001', 'SKU-002', 'SKU-003']) %}

<table>
    <tr>
    {% for product in products %}
        <td class="product-card">
            <img src="{{ product.image }}" alt="{{ product.name }}" />
            <h3>{{ product.name }}</h3>
            <p>${{ product.price }}</p>
            <a href="{{ product.url }}">Buy Now</a>
        </td>
    {% endfor %}
    </tr>
</table>

Available Product Fields

FieldDescriptionExample
product.idProduct ID / SKUSKU-123
product.nameProduct nameClassic White T-Shirt
product.descriptionProduct descriptionA comfortable everyday tee...
product.imageImage URLhttps://cdn.example.com/tshirt.jpg
product.urlProduct page URLhttps://store.com/products/tshirt
product.priceRegular price29.99
product.price_saleSale price (if applicable)19.99

Dynamic Fields

Dynamic fields are placeholders replaced with real customer data at send time. Just type the field name — including curly braces — directly into your HTML.

General Fields

Available in all email templates:

FieldDescription
{store_name}Your store name
{first_name}Customer's first name
{last_name}Customer's last name
{user_email}Customer's email address
{date_joined}Date the customer joined

Loyalty Fields

FieldDescription
{loyalty_points}Current points balance
{loyalty_tier}Current loyalty tier
{loyalty_tier_points}Points within the current tier
{loyalty_cashback}Cashback balance
{loyalty_points_value}Monetary value of the customer's points
{loyalty_date_joined}Date the customer joined the loyalty program
{loyalty_total_earned}Total points earned all-time
{loyalty_total_spent}Total points spent all-time

Link Fields

FieldDescription
{referral_url}Customer's unique referral link
{view_in_browser}Link to view the email in a browser
{manage_preferences}Link to email preference settings
{unsubscribe}Unsubscribe link

Example: Combining Products and Dynamic Fields

<p>Hi {first_name}, check out these picks for you!</p>

{% set products = get_products_by_id(['SKU-001', 'SKU-002']) %}

{% for product in products %}
<div class="product-card">
    <img src="{{ product.image }}" alt="{{ product.name }}" />
    <h3>{{ product.name }}</h3>
    <p>${{ product.price }}</p>
    <a href="{{ product.url }}">Shop Now</a>
</div>
{% endfor %}

<p>You have {loyalty_points} points — <a href="{referral_url}">refer a friend</a> to earn more!</p>

Note: Product fields use double curly braces {{ }} as part of the template engine. General dynamic fields like {first_name} use single curly braces {} and are replaced at send time.


Adding CSS Styles

Write your CSS in the CSS Style editor. Styles are automatically inlined into the HTML for maximum compatibility across email clients.

.product-card {
    text-align: center;
    padding: 16px;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
}

.product-card img {
    max-width: 200px;
    height: auto;
}

.product-card h3 {
    font-size: 18px;
    color: #333;
    margin: 12px 0 4px;
}

.price {
    font-size: 16px;
    font-weight: bold;
    color: #2a9d8f;
}

.product-card a {
    display: inline-block;
    padding: 10px 24px;
    background-color: #2a9d8f;
    color: #ffffff;
    text-decoration: none;
    border-radius: 4px;
    margin-top: 12px;
}

Font Options

Choose a custom font for your HTML block:

  • Default Font — inherits the email template's base font
  • Web Safe Font — fonts supported across all email clients (Arial, Georgia, Verdana, etc.)
  • Google Font — broader variety, though support varies by email client

Template Logic

Use built-in template logic to conditionally show content or format values.

Conditional Content

{% if product.price_sale %}
    <p><s>${{ product.price }}</s> <strong>${{ product.price_sale }}</strong></p>
{% else %}
    <p>${{ product.price }}</p>
{% endif %}

Number Formatting

<p>${{ product.price | number_format(2) }}</p>
<!-- Output: $29.99 -->

Text Formatting

<p>{{ product.name | upper }}</p>
<!-- Output: CLASSIC WHITE T-SHIRT -->

<p>{{ product.name | lower }}</p>
<!-- Output: classic white t-shirt -->

Checking List Length

{% set products = get_products_by_id(['SKU-001', 'SKU-002', 'SKU-003']) %}

{% if products | length > 0 %}
    <h2>Recommended for you</h2>
    {% for product in products %}
        <p>{{ product.name }} - ${{ product.price }}</p>
    {% endfor %}
{% endif %}

Template Syntax Reference

FeatureSyntaxExample
Set a variable{% set x = value %}{% set product = get_product_by_id('SKU-1') %}
If / else{% if condition %}...{% else %}...{% endif %}{% if product.price_sale %}On Sale!{% endif %}
Loop{% for item in list %}...{% endfor %}{% for p in products %}{{ p.name }}{% endfor %}
Output a value{{ variable }}{{ product.name }}
Format number{{ value | number_format(2) }}{{ product.price | number_format(2) }}
Uppercase{{ value | upper }}{{ product.name | upper }}
Lowercase{{ value | lower }}{{ product.name | lower }}
Escape HTML{{ value | escape }}{{ product.description | escape }}
Get length{{ list | length }}{{ products | length }}

Tips and Best Practices

  • Use tables for layout. Email clients have limited CSS support — table-based layouts render far more consistently than flexbox or grid.
  • Use full image URLs. Images must be hosted at an absolute URL (e.g., https://...). Relative paths won't work in emails.
  • Preview before sending. The editor renders a live preview of your HTML block — use it to verify your products and layout look right.
  • Wrap sale prices in a conditional. Not all products have a price_sale value. Use an {% if %} block to avoid showing blank or broken prices.
  • Double-check your product IDs. If an ID doesn't match a product in your catalog, that product will be silently skipped.
  • Keep your CSS simple. Shadows, gradients, and animations aren't supported by most email clients — stick to basic styles for reliable rendering.
Was this article helpful?
0 out of 0 found this helpful