Templates

Template variables

All available variables for personalising your email templates.

Templates are HTML files with {{ variable }} placeholders that Vlozi replaces with real values at send time. The syntax is Mustache-style — whitespace inside the braces is tolerated, so {{name}}, {{ name }}, and {{ name }} all work.

Variable reference

Subscriber variables

Resolved from the recipient's subscriber record.

Variable Example value Notes
{{ subscriber.name }} Alice Falls back to "there" when the subscriber has no name set
{{ subscriber.email }} alice@example.com The subscriber's email address
{{ subscriber.tags }} newsletter, vip All tags as a comma-separated string
{{ subscriber.metadata.KEY }} (depends on your data) Any key from the subscriber's metadata object. Use dot notation: {{ subscriber.metadata.plan }}
Variable Example value Notes
{{ unsubscribe_url }} https://api.vlozi.app/newsletter/public/unsubscribe?... HMAC-signed, unique per recipient. Always include in every template.

IMPORTANT

Every template sent to subscribers must include {{ unsubscribe_url }}. It is a legal requirement in most jurisdictions (CAN-SPAM, GDPR) and the Vlozi platform will warn you if it is missing.

Campaign variables

Variable Example value Notes
{{ campaign.name }} June Newsletter The campaign's internal name
{{ campaign.subject }} What's new in June The email subject line

Brand variables

Pulled from your Comms sender settings. Set them in Settings → Email Sender.

Variable Example value Notes
{{ tenant.name }} My Company Your sender name
{{ tenant.from_email }} hello@mycompany.com Your sender email address
{{ brand.logo_url }} https://cdn.example.com/logo.png Your brand logo URL. Falls back to an empty string — keep <img src=""> in mind.
{{ brand.primary_color }} #FF5436 Your brand's primary hex colour, including the #

Date variables

Variable Example value Notes
{{ now.year }} 2026 Current UTC year. Useful for footer copyright: © {{ now.year }} {{ tenant.name }}

Blog post variables

Only available in campaigns triggered by a blog post publish. In manually created campaigns, these resolve to empty string.

Variable Example value Notes
{{ post.title }} How to get started with X The blog post title
{{ post.excerpt }} A short intro... The post excerpt
{{ post.slug }} how-to-get-started-with-x Use to build the post URL
{{ post.cover_url }} https://cdn.example.com/cover.jpg Featured image URL; empty string when none
{{ post.author_name }} Dipanshu Vishwakarma Author's display name

Writing a minimal template

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /></head>
<body style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 24px;">
 
  <p>Hi {{ subscriber.name }},</p>
 
  <!-- Your email body here -->
 
  <hr style="border: none; border-top: 1px solid #eee; margin: 32px 0;" />
  <p style="color: #999; font-size: 12px; text-align: center;">
    © {{ now.year }} {{ tenant.name }} ·
    <a href="{{ unsubscribe_url }}" style="color: #999;">Unsubscribe</a>
  </p>
 
</body>
</html>

HTML escaping

User-controlled substitutions in the HTML body are HTML-escaped before insertion (&, <, >, ", '). This means:

  • A subscriber name like <script>alert(1)</script> renders as &lt;script&gt;alert(1)&lt;/script&gt; — safe.
  • The {{ unsubscribe_url }} is not escaped (it's a URL we built, not user input).
  • Plain text body (textBody) substitutions are not escaped.

You do not need to escape variables yourself — the renderer does it for you.

Template snapshots

When you create a campaign and select a template, the template body is copied into the campaign at that moment. Changes to the template after that point do not affect the campaign. This is intentional:

  • Scheduled campaigns are deterministic — the email that fires at 9 AM Tuesday is exactly the email you approved when you scheduled it
  • Deleting a template does not break any campaign based on it

The dashboard shows a "Based on [Template Name]" attribution on the campaign, but the template is not referenced at send time.

Unknown variables

If your template contains a token that isn't in the list above — for example {{ user.first_name }} or {{ myCustomToken }} — Vlozi will:

  1. Pass it through unchanged in the email body (the literal text {{ user.first_name }} appears)
  2. Log a warning for each unknown token per send

The template editor warns you about unknown tokens when you save, but it won't prevent saving. This lets you build templates incrementally — just make sure to check the token list before you send.

Limitations in v1

  • No conditionals{% if %} / {% else %} / {% endif %} blocks are not supported. The text is sent literally.
  • No loops{% for %} blocks are not supported.
  • No filters{{ name | upper }} style filters are not supported.
  • One level of metadata nesting{{ subscriber.metadata.plan.name }} resolves plan only, not .name inside it.

These may be added in a future version.

Newsletter · TemplatesEdit on GitHub