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

  1. Create a template from Templates: use a starter, Visual builder, or Paste HTML for markup you already have.
  2. Open Edit — block editor for blocks templates, or the raw HTML / plain-text editor for html templates (includes preheader and Test send).
  3. Use {{variable}} placeholders in subject, copy, and button URLs.
  4. Publish freezes an immutable version. Sends always use that version — draft edits never break live traffic.
  5. 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" } creates EmailTemplateVersion and points published_version_id at it. Each version stores an immutable format snapshot (html or blocks) so restoring an older version brings back the correct editor mode even if the live draft was converted.
  • GET /templates/{id}/versions lists 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.