Campaigns

Blog integration

Automatically send a newsletter campaign when you publish a blog post.

Connect your Vlozi Blog to your newsletter so a campaign goes out automatically every time you publish a post — no manual step required.

How it works

  1. You publish a post in the Vlozi Blog dashboard (or via the API)
  2. Blog notifies the newsletter service in the background
  3. Newsletter checks if you have a blog binding configured
  4. If yes — a campaign is auto-created and fired to your configured audience
  5. Subscribers receive an email with your post details

The entire flow is fire-and-forget from the blog's perspective. If the newsletter service is down or returns an error, your post still publishes successfully.

Setting up the blog binding

In the dashboard → NewsletterBlog Integration:

Setting Required Description
Template Yes Which email template to use for post notifications. Should include {{ post.title }}, {{ post.excerpt }}, etc.
Subject template Yes Email subject line with post variables: {{title}} or {{excerpt}}
Segment No Send to a specific segment. Leave empty to send to all confirmed subscribers.

Once configured, every published post automatically triggers a campaign.

Post variables in templates

When an email is sent from a blog publish event, your template body has access to these post-specific variables in addition to the standard subscriber variables:

Variable Value
{{ post.title }} The post's title
{{ post.excerpt }} The post's excerpt
{{ post.slug }} The post's slug — use to build the URL
{{ post.cover_url }} Featured image URL (empty string if none)
{{ post.author_name }} Author's display name

Building the post URL

The SDK doesn't know your site's URL — build it from the slug:

<a href="https://yoursite.com/blog/{{ post.slug }}">Read the full post →</a>
{% if post.cover_url %}
<img src="{{ post.cover_url }}" alt="{{ post.title }}" style="width:100%; max-width:600px;" />
{% endif %}

NOTE

These variables only work in campaigns triggered by a blog publish. In manually created campaigns, {{ post.* }} tokens resolve to an empty string.

Subject line tokens

The subject template (configured in the blog binding settings) uses a flat token format:

Token Value
{{title}} The post's title
{{excerpt}} The post's excerpt

Example: New post: {{title}}

WARNING

The subject line uses {{title}} (no spaces, no dot-namespace). The template body uses {{ post.title }} (spaces, dot-namespace). These are two different systems. Do not use {{ post.title }} in the subject field — it will not be replaced.

This is a known inconsistency (tracked internally as B6) and will be unified in a future release.

Preventing duplicate sends

Each blog post can only trigger one campaign. If a post is published, unpublished, and re-published, the newsletter fires only on the first publish. The system uses a unique constraint on (source_post_id, tenant_id) to prevent duplicate campaigns for the same post.

Example template for blog posts

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <style>
    body { font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 24px; }
    .post-image { width: 100%; border-radius: 8px; margin-bottom: 20px; }
    .read-more { display: inline-block; background: {{ brand.primary_color }}; color: #fff;
                 padding: 12px 24px; text-decoration: none; border-radius: 6px; }
  </style>
</head>
<body>
  <p>Hi {{ subscriber.name }},</p>
  <p>We just published a new post:</p>
 
  <h2>{{ post.title }}</h2>
 
  {% if post.cover_url %}
  <img src="{{ post.cover_url }}" alt="{{ post.title }}" class="post-image" />
  {% endif %}
 
  <p>{{ post.excerpt }}</p>
 
  <a href="https://yoursite.com/blog/{{ post.slug }}" class="read-more">
    Read the full post →
  </a>
 
  <hr style="margin-top: 40px; border: none; border-top: 1px solid #eee;" />
  <p style="color: #999; font-size: 12px;">
    {{ tenant.name }} · <a href="{{ unsubscribe_url }}">Unsubscribe</a>
  </p>
</body>
</html>

TIP

Conditional blocks ({% if %}) are not supported in v1. The snippet above shows the pattern for illustration — the {% if %} block will be sent literally if your template engine doesn't process it. Use a plain <img> tag and accept that it may be an empty src="" when no cover image is set (which most email clients handle gracefully).

Newsletter · CampaignsEdit on GitHub