Development

Welcome email template: A developer’s guide to MJML and Mailjet (2025)

Learn how to code a welcome email template with MJML and Mailjet's template language in this step by step tutorial, with code samples and examples.
Image for Welcome email template: A developer’s guide to MJML and Mailjet (2025)
August 30, 2018

Welcome emails are your first impression with new users, arriving at the moment of maximum engagement and routinely outperforming regular campaigns on opens and clicks. This comprehensive guide will walk you through building a responsive, personalized welcome email template using MJML and Mailjet’s powerful templating system.

By the end of this tutorial, you’ll have a production-ready workflow that includes creating reusable templates, implementing dynamic personalization, and tracking performance metrics, all through Mailjet’s email API.

What you’ll build

Here’s what we cover in this guide:

  • Responsive email template coded in MJML for cross-client compatibility
  • Dynamic personalization using Mailjet’s templating language
  • Production-ready API workflow for creating, sending, and tracking emails
  • Performance monitoring with webhooks and analytics

Prerequisites

Before getting started, ensure you have:

  • A Mailjet account with API keys
  • A validated sender domain with SPF/DKIM configured in Senders & Domains
  • Optional: MJML CLI or editor for compiling MJML to HTML

Quick start (TL;DR)

For developers who want to jump straight in:

  • Write responsive layouts in MJML, then compile to HTML
  • Create reusable templates in Mailjet with TemplateLanguage enabled
  • Use variables like {{data:firstname:”there”}} and {{var:plan}} for personalization
  • Send via Send API v3.1 using TemplateID, Variables, CustomCampaign, and URLTags
  • Test safely with SandboxMode, track with webhooks, and measure with statcounters
  • Verify your domain (SPF/DKIM) for optimal deliverability

Step 1: Create your MJML welcome email template

MJML provides a fast, mobile-first structure that compiles into bulletproof HTML. Here’s a lean welcome email template that includes personalization placeholders:

                            

                                <mjml>
  <mj-head>
    <mj-title>Welcome to {{data:brand:"our"}}!</mj-title>
    <mj-preview>Let's get you set up in minutes.</mj-preview>
  </mj-head>
  <mj-body background-color="#ffffff">
    <mj-section padding="24px 0">
      <mj-column width="100%">
        <mj-image 
          src="https://assets.mailjet.com/logo.png" 
          alt="{{data:brand:"Brand"}} logo" 
          width="120px" />
        <mj-spacer height="12px" />
        <mj-text font-size="22px" font-weight="700">
          Hi {{data:firstname:"there"}}, welcome aboard!
        </mj-text>
        <mj-text font-size="16px" line-height="1.6">
          You've created a {{var:plan:"free"}} account. Here are 3 quick steps to get value fast:
        </mj-text>
        <mj-button 
          href="{{var:primary_cta_url:"https://www.example.com/start"}}" 
          background-color="#0a84ff">
          Complete your profile
        </mj-button>
        <mj-text font-size="14px" color="#637381">
          Prefer docs? Visit our Getting Started guide.
        </mj-text>
        <mj-button 
          href="{{var:docs_url:"https://dev.mailjet.com/email/guides/getting-started/"}}" 
          background-color="#1C1C1C">
          Read docs
        </mj-button>
        <mj-divider border-color="#EAEAEA" />
        <mj-text font-size="13px" color="#637381">
          If you didn't create this account, ignore this email or contact support.
        </mj-text>
      </mj-column>
    </mj-section>
    <mj-section padding="0 0 24px">
      <mj-column>
        <mj-text font-size="12px" color="#98A2B3">
          Sent by {{data:brand:"Brand"}} • {{data:brand_address:"Address line"}} • 
          Manage preferences in your account.
        </mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

                            
                        

Understanding the personalization syntax

  • {{data:…}}: Reads contact properties already stored in Mailjet (e.g., firstname, brand)
  • {{var:…}} – Reads variables you pass in the Send API call (e.g., plan, URLs)
  • Fallback values – Use the : “default” syntax to provide safe fallbacks

Step 2: Store your template using the template API

There are two parts to this step.

Create the template container

First, create a template container in Mailjet:

                            

                                POST https://api.mailjet.com/v3/REST/template
Content-Type: application/json
Authorization: Basic {base64_encoded_api_key:secret_key}

{
  "Name": "Onboarding – Welcome",
  "Locale": "en_US",
  "OwnerType": "user",
  "IsTextPartGenerationEnabled": "true",
  "Description": "Responsive MJML welcome template with personalization."
}

                            
                        

Add your compiled HTML content

After compiling your MJML to HTML, add it as template content:

                            

                                POST https://api.mailjet.com/v3/REST/template/{TEMPLATE_ID}/detailcontent
Content-Type: application/json

{
  "Html-part": "<!-- paste your compiled HTML here -->",
  "Text-part": "Hi {{data:firstname:\"there\"}}, welcome to {{data:brand:\"our\"}}...",
  "Headers": {
    "From": "\"Customer Success\" <hello@yourdomain.com>",
    "Subject": "Welcome, {{data:firstname:\"friend\"}} — let's get you set up",
    "Reply-to": "support@yourdomain.com"
  }
}

                            
                        

Pro Tip: Use Headers in detailcontent to set default From/Subject/Reply-To values. You can still override them at send time.

Step 3: Implement dynamic personalization

Mailjet’s templating language allows you to create highly personalized email experiences:

Common personalization patterns

  • Locale-based content: Store locale on contacts and pass locale-specific URLs via Variables
  • Plan tier variations: Use {{var:plan}} for copy variations (“Pro trial”, “Free plan”, etc.)
  • Safe fallbacks: {{data:firstname:”there”}} prevents awkward “Hi ,” greetings

Enabling template language

Set TemplateLanguage: true in your send call to render all variables and contact properties.

Step 4: Send emails with the Send API v3.1

Once you’re ready, you can now do a:

Production send with full personalization

                            

                                POST https://api.mailjet.com/v3.1/send
Content-Type: application/json

{
  "Messages": [
    {
      "From": { 
        "Email": "hello@yourdomain.com", 
        "Name": "Customer Success" 
      },
      "To": [{ 
        "Email": "new.user@example.com", 
        "Name": "New User" 
      }],
      "TemplateID": TEMPLATE_ID,
      "TemplateLanguage": true,
      "Subject": "Welcome, {{data:firstname:\"friend\"}} — let's get you set up",
      "Variables": {
        "plan": "free",
        "primary_cta_url": "https://www.example.com/start",
        "docs_url": "https://dev.mailjet.com/email/guides/getting-started/"
      },
      "CustomCampaign": "onboarding_welcome",
      "DeduplicateCampaign": true,
      "URLTags": "utm_source=welcome&utm_medium=email&utm_campaign=onboarding",
      "CustomID": "welcome_0001",
      "EventPayload": "new_signup,region=US,plan=free"
    }
  ]
}
                            
                        

Safe testing with sandbox mode

For testing without sending real emails, add “SandboxMode”: true:

                            

                                {
  "SandboxMode": true,
  "Messages": [
    // ... your message configuration
  ]
}
                            
                        

This validates your payload and returns any errors without actually delivering the email.

Step 5: Configure authentication and deliverability

Domain verification

  1. Add your domain in Mailjet’s Senders & Domains section
  2. Configure SPF and DKIM records in your DNS
  3. Verify setup using the /dns/{domain}/check endpoint
                            

                                GET https://api.mailjet.com/v3/REST/dns/{domain}/check
                            
                        

Proper domain authentication significantly improves inbox placement for welcome emails.

Step 6: Track performance and optimize

We also recommend you implement:

Real-time event tracking

Configure webhooks to receive delivery events:

                            

                                POST https://api.mailjet.com/v3/REST/eventcallbackurl
{
  "Url": "https://your-app.com/mailjet-webhook",
  "EventType": "sent,open,click,bounce,blocked,spam,unsub"
}
                            
                        

Use CustomID or EventPayload in your sends to correlate events with users in your system.

Performance analytics

Retrieve aggregated metrics programmatically:

                            

                                GET https://api.mailjet.com/v3/REST/statcounters
?CounterSource=APIKey
&CounterTiming=Message
&CounterResolution=Lifetime

                            
                        

Track key metrics like:

  • MessageSentCount
  • MessageOpenedCount
  • MessageClickedCount

Summary

You now have a complete workflow for building, personalizing, and tracking welcome emails at scale. This approach combines MJML’s responsive design capabilities with Mailjet’s powerful templating and analytics features.

Next steps

  1. Compile your MJML template to HTML
  2. Create and store your template via the Template API
  3. Test thoroughly using sandbox mode
  4. Configure webhooks for real-time event tracking
  5. Monitor performance and iterate based on analytics

With this foundation, you can create sophisticated email experiences that adapt to user preferences, plan types, and lifecycle stages—all from a single, maintainable template.