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
- 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.
- 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}})
- 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> |
Related
- CLI Config — how credentials are stored and managed
- Analytics — same CLI-managed pattern for configuring external providers
- Authentication — CLI auth for deploying sites
- User Auth & Gating — user-facing auth flows that send verification and password reset emails