notiflowsDocs
LearnBuilding Notiflows

Templates

Create dynamic notification content with Liquid templating

Templates define the content of your notifications. Notiflows uses Liquid templating to insert dynamic content into your notifications.

Variable Contexts

Three variable contexts are available in every template:

ContextDescriptionExample
recipient.*Recipient user attributes{{ recipient.first_name }}
actor.*User who triggered the notification{{ actor.email }}
data.*Custom payload from the API call{{ data.order_id }}

These contexts are populated from the data you pass when running a notiflow.

Basic Syntax

Insert variables with double curly braces:

Hi {{ recipient.first_name }},

{{ actor.first_name }} left a comment on your post.

Filters

Transform values with filters:

{{ recipient.first_name | capitalize }}
{{ data.price | money }}
{{ data.created_at | date: "%B %d, %Y" }}

Conditionals

Use conditional logic:

{% if data.discount %}
You saved {{ data.discount }}!
{% endif %}

{% if recipient.custom_fields.plan == "premium" %}
As a premium member, you get early access.
{% else %}
Upgrade to premium for early access.
{% endif %}

Loops

Iterate over arrays:

Your items:
{% for item in data.items %}
- {{ item.name }}: {{ item.price }}
{% endfor %}

Template Formats by Channel

Email

Email templates support three content types:

  • Visual — Drag-and-drop editor for rich HTML emails
  • HTML — Raw HTML with full control over layout
  • Plaintext — Simple text emails
Subject: Order #{{ data.order_id }} confirmed

Hi {{ recipient.first_name }},

Thanks for your order! Here's what you purchased:

{% for item in data.items %}
- {{ item.name }} ({{ item.quantity }}x)
{% endfor %}

Total: {{ data.total }}

SMS

SMS templates use plaintext only:

Hi {{ recipient.first_name }}, your order #{{ data.order_id }} has shipped! Track it: {{ data.tracking_url }}

Mobile Push

Mobile push templates have a title and body field (both plaintext):

Title: New message from {{ actor.first_name }}
Body: {{ data.message_preview }}

Web Push

Web push templates have a title and body (both plaintext), plus optional icon, image, and action URL fields:

FieldRequiredExample
TitleYes{{ actor.first_name }} commented on your post
BodyYes{{ data.comment_preview }}
Icon URLNohttps://yourapp.com/icon.png
Image URLNo{{ data.post_image_url }}
Action URLNohttps://yourapp.com/posts/{{ data.post_id }}

In-App

In-app templates have a body (markdown) and an optional action URL:

Body: **{{ actor.first_name }}** commented on your post: "{{ data.comment_preview }}"
Action URL: {{ data.post_url }}

Chat (Slack)

Chat templates support markdown or JSON for rich formatting:

Markdown:

*New order #{{ data.order_id }}*
Customer: {{ actor.first_name }} {{ actor.last_name }}
Total: {{ data.total }}

JSON (Slack Block Kit):

{
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Order #{{ data.order_id }}*\nCustomer: {{ actor.first_name }}"
      }
    }
  ]
}

Digest Templates

When using a digest step, templates have access to the collected events via the digest context:

VariableDescription
digest.total_itemsNumber of events collected in the digest window
digest.itemsArray of collected events
digest.items[].dataThe original notification data payload
digest.items[].actorThe actor who triggered the event (id, external_id, email, first_name, last_name)
digest.items[].recipientThe recipient of the notification (same fields as actor)
You have {{ digest.total_items }} new comments:

{% for item in digest.items %}
- {{ item.actor.first_name }}: {{ item.data.message }}
{% endfor %}

On this page