Visual template builder
Non-technical teammates design emails in the dashboard builder. Engineers send with a stable alias:
await client.emails.send({
from: '[email protected]',
to: '[email protected]',
template: {
id: 'welcome',
variables: { name: 'Ada', dashboard_url: 'https://app.example.com' },
},
})How it works
- Create a template from Templates: use a starter, Visual builder, or Paste HTML for markup you already have.
- Open Edit — block editor for
blockstemplates, or the raw HTML / plain-text editor forhtmltemplates (includes preheader and Test send). - Use
{{variable}}placeholders in subject, copy, and button URLs. - Publish freezes an immutable version. Sends always use that version — draft edits never break live traffic.
- Restore an older version from the API if you need to roll back the draft, then publish again.
Formats
| Format | Meaning |
|---|---|
blocks |
Visual builder document (design JSON) compiled to email-safe HTML |
html |
Raw HTML/text — editable in the code editor; switching to the visual builder permanently deletes HTML (with confirmation) |
Global CSS
design.settings.globalCss lets you style a whole template with ordinary CSS instead of
per-block controls. The Global CSS panel in the builder inspector edits it, and shows which
rules get inlined.
Rules whose selector is a bare tag — body, p, h1, h2, h3, a, img, hr — are merged
into those elements' style attributes on render, and override block styling. Everything else
(class and id selectors, pseudo-classes, descendant selectors, media queries) goes into a
<style> block.
The split is not a limitation of the parser; it is what survives the inbox. Gmail drops
<style> on clipped and forwarded messages, and Outlook renders through Word, so anything that
must be reliable has to be inline. Class selectors are still useful for markup inside an
html block.
@import is stripped and CSS cannot inject markup. The editable canvas does not preview global
CSS — switch to Preview for the exact render.
Code view
The Code tab in the builder shows the exact HTML that publish stores and sends, with
{{variable}} placeholders left in place, plus a copy button. It is read-only for blocks
templates — the canvas and Global CSS are the inputs that produce it.
format: 'html' templates open in the same editor, writable, with separate HTML and plain-text
tabs.
Keeping templates in git
supersendtx templates push <file> --alias <alias> upserts a template from a local .html,
.txt, or React Email component. Module files are imported and rendered in your process, so
only the resulting HTML and text are uploaded. See
Templates API — CLI and the
React Email guide.
Versioning
POST /templates/{id}with{ "action": "publish" }createsEmailTemplateVersionand pointspublished_version_idat it. Each version stores an immutableformatsnapshot (htmlorblocks) so restoring an older version brings back the correct editor mode even if the live draft was converted.GET /templates/{id}/versionslists history.POST /templates/{id}/versions/{n}with{ "action": "restore" }loads that snapshot into the draft (does not auto-publish).
Images
Prefer PNG/JPEG/WebP at absolute HTTPS URLs. When R2 is configured (R2_* env vars), the builder can upload images via POST /assets (presigned PUT). Otherwise paste a public URL.
Client compatibility
The blocks renderer emits table-based HTML with Outlook (MSO) conditionals, mobile stacking, dark-mode meta, bulletproof buttons, and a hidden preheader — the same output for live preview and publish.