← All skills
email-template-builder
Use when adding transactional email to a product, migrating providers, refactoring templates for a11y, or adding i18n. Covers React Email, Resend, Postmark, SendGrid, SES, dark mode, spam scoring.
About this skill
Use when adding transactional email to a product, migrating providers, refactoring templates for a11y, or adding i18n. Covers React Email, Resend, Postmark, SendGrid, SES, dark mode, spam scoring.
SKILL.md
email-template-builder.SKILL.mdPlace it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review the contents and run it in a controlled environment first.
---
name: email-template-builder
description: Use when adding transactional email to a product, migrating providers, refactoring templates for a11y, or adding i18n. Covers React Email, Resend, Postmark, SendGrid, SES, dark mode, spam scoring.
category: Engineering
version: 1.0.0
tools: []
---
# Email Template Builder
**Category:** Engineering · **Domain:** Transactional Email / Communications Infrastructure
Build complete transactional email systems: React Email templates, provider integration, i18n support, dark mode, spam-score optimization, and analytics tracking. Return production-ready code for Resend, Postmark, SendGrid, or AWS SES directly in the chat as copy-pasteable TSX/TypeScript.
## Core Capabilities
- React Email templates (welcome, verification, password reset, invoice, notification, digest)
- MJML templates for maximum email-client compatibility
- Multi-provider support behind one unified send interface
- i18n/localization with typed translation keys
- Dark mode support using `prefers-color-scheme` media queries
- Spam Score optimization checklist
- Open/click tracking with UTM parameters
## When to Use
- Setting up transactional email for a new product
- Migrating from a legacy email system
- Adding new email types (invoice, digest, notification)
- Debugging email deliverability issues
- Implementing i18n for email templates
## Suggested Project Structure
```
emails/
├── components/layout/ # base layout, buttons
├── components/partials/ # header, footer
├── templates/ # welcome, verify-email, password-reset, invoice, notification, weekly-digest
├── lib/ # send.ts (unified send), providers/ (resend, postmark, ses), tracking.ts
├── i18n/ # en.ts, de.ts, ...
```
## Base Email Layout
Every template wraps a shared `EmailLayout` component: `Html`/`Head`/`Body`/`Container` from `@react-email/components`, a `Preview` line for the inbox preview text, a header section with the logo, the template's content slot, and a footer with company address and an unsubscribe link. Dark mode is handled with a `<style>` block using `@media (prefers-color-scheme: dark)` to override background, text, and divider colors — never rely on JS for dark mode in email, since most clients strip it.
```tsx
<Html lang="en">
<Head>
<style>{`
@media (prefers-color-scheme: dark) {
.email-body { background-color: #0f0f0f !important; }
.email-text { color: #e5e5e5 !important; }
}
`}</style>
</Head>
<Preview>{preview}</Preview>
<Body className="email-body">
<Container className="email-container">
{/* header, {children}, footer with unsubscribe link */}
</Container>
</Body>
</Html>
```
## Welcome Email Pattern
A welcome email needs: a personalized heading, a short value statement (mention the trial length explicitly, e.g. "You've got 14 days to explore"), a single primary CTA button ("Confirm Email Address"), a plain-text fallback link beneath the button for clients that strip buttons, and a short bulleted list of first next actions (connect a project, invite the team, set up notifications). Keep exactly one CTA — competing buttons hurt both conversion and spam score.
## Invoice Email Pattern
An invoice email needs: an invoice-number heading, a meta box with invoice date / due date / amount due (use `Intl.NumberFormat` with the correct currency, and always store/format cents as integers to avoid floating-point rounding errors), a line-item table with alternating row shading for scanability, a total row, and a "Download PDF Invoice" CTA. Compute the formatted total once and reuse it in both the meta box and the preview text.
## Unified Send Function
Route every email type through one `sendEmail(to, payload)` function that looks up a `{ component, subject }` pair by `payload.type`, renders the React component to HTML, appends UTM tracking parameters to any absolute URLs it contains, and calls the active provider's SDK (`resend.emails.send`, or the Postmark/SES equivalent) with a `tags`/`metadata` field carrying the email type — that tag is what makes provider-side analytics queryable by template later. Keep provider selection behind this one function so switching providers (Resend ↔ Postmark ↔ SES) touches one file, not every template.
## Local Preview
Run a local preview server (the `email` CLI, or an equivalent dev command) pointed at the templates directory to see every template with hot reload before sending a real message — never validate a template by sending yourself a live email during development.
## i18n Support
Keep translations as small typed objects keyed by template name, with each string either a plain value or a function of the template's props (e.g. `body: (days) => \`You've got ${days} days...\`` in English, `\`Du hast ${days} Tage Zeit...\`` in German). Select the locale object once per send (`const t = locale === "de" ? de : en`) rather than branching inside the JSX — that keeps every template locale-agnostic.
## Spam Score Optimization Checklist
- Sender domain has SPF, DKIM, and DMARC records configured
- From address uses your own domain, not a free consumer domain (gmail.com, hotmail.com)
- Subject line under 50 characters, no ALL CAPS, no "FREE!!!"
- Text-to-image ratio: at least 60% text
- Plain-text version included alongside the HTML
- Unsubscribe link in every marketing email (CAN-SPAM, GDPR)
- No URL shorteners — use full branded links
- No red-flag words in the subject: "guarantee", "no risk", "limited time offer"
- Single CTA per email — not five different buttons
- Image alt text on every image
- HTML validates — no broken tags
- Test with a deliverability checker before the first real send; target a 9+/10 Spam Score
## Analytics Tracking
Append UTM parameters (`utm_source`, `utm_medium`, `utm_campaign`) to every absolute link in the rendered HTML before sending, tagging each send with its template type so open/click data can be grouped by email type in the provider dashboard or downstream analytics tool.
## Provider Notes
- **Resend** — simplest API, good defaults, React Email first-class support
- **Postmark** — strong deliverability reputation, separate transactional/broadcast streams
- **SendGrid** — broad feature set, more configuration surface
- **AWS SES** — cheapest at volume, requires more manual reputation/warm-up management
Return the requested template(s), the send function, and the Spam Score checklist results directly in the chat as code blocks the user can paste into their project; use web_search to check current SPF/DKIM/DMARC guidance for a specific provider if deliverability is in question.
Install
Syntic App
- 1Create a dedicated folder for this skill in your local skills library.
- 2Place SKILL.md into that folder.
- 3Restart Syntic and invoke this skill on matching tasks.
Syntic Code (CLI)
- 1Save SKILL.md in your local Syntic Code skills directory.
- 2Keep related files in the same skill folder.
- 3Run in a safe environment and validate outputs.