Email Templates

Define transactional emails as markdown files in emails/. The build engine compiles them into a JSON manifest (site/_emails.json) that your backend reads to send emails.

Quick setup

  1. Configure your email provider using the CLI:
sitemd config setup email

This walks you through choosing a provider and entering your API key. Set the default sender address in settings/email.md:

---
from: My App <noreply@example.com>
---

Every template inherits this address unless it specifies its own from. If you skip this step, you must set from in every individual template.

  1. Create a template in emails/auth/welcome.md:
---
id: welcome
from: My App <noreply@example.com>
subject: Welcome to {{appName}}
---

## Welcome, {{name}}

Thanks for signing up for **{{appName}}**. You're all set.

[Get started]({{dashboardUrl}})
  1. Build your site. The compiled templates appear in site/_emails.json.

Template format

Each template is a markdown file in a subdirectory of emails/. Subdirectories are categories — organize however you like (auth/, billing/, notifications/, etc.).

Frontmatter fields:

Field Required Description
id Yes Unique identifier for this template
subject Yes Email subject line (supports {{variables}})
from Yes* Sender address — falls back to settings/email.md default if omitted

*Every compiled template must have a non-empty from value. Set it per-template, or set a global default in settings/email.md. If both are missing, the template compiles with an empty sender and email providers will reject the send request.

Body: Standard markdown. Supports headings, bold, code, links, and paragraphs. Uses {{variableName}} for dynamic values.

Variables

Use {{variableName}} anywhere in the subject or body. Each unique variable name is extracted and listed in the compiled output so your backend knows what to pass when sending.

---
id: password-reset
from: My App <noreply@example.com>
subject: Reset your password
---

## Reset your password

Click the link below to reset your password:

[Reset password]({{resetUrl}})

This link expires in 1 hour. If you didn't request this, ignore this email.

Compiles to:

{
  "id": "password-reset",
  "category": "auth",
  "from": "My App <noreply@example.com>",
  "subject": "Reset your password",
  "vars": ["resetUrl"],
  "html": "<h2>Reset your password</h2>..."
}

Your backend interpolates {{resetUrl}} at send time.

Supported providers

Configure the provider using sitemd config setup email. The interactive setup guides you through the credentials for each provider. You can also set values directly with sitemd config set — see CLI Config for all keys.

Provider provider value Required fields
Resend resend apiKey
SendGrid sendgrid apiKey
Postmark postmark apiKey
Mailgun mailgun apiKey
AWS SES ses region, accessKeyId, secretAccessKey
SMTP smtp host, port, user, pass

Build output

Every build compiles emails/ into site/_emails.json — a JSON array of templates with their compiled HTML, extracted variables, and resolved from address. If the emails/ directory doesn't exist, nothing is generated.

The manifest is designed to be consumed by any backend. Read the JSON, find the template by id, interpolate the {{variables}} in subject and html, and send via your provider.

Supported markdown

Email HTML is intentionally minimal for maximum email client compatibility:

Markdown HTML
## Heading <h2>
### Heading <h3>
**bold** <strong>
`code` <code>
[text](url) <a href="url">
Plain text <p>