Emails (mailables)

renderMailable(spec) turns a structured spec (greeting, paragraphs, action button, salutation) into a responsive, inline-styled HTML email anda plaintext version — the Markdown-mail experience, no build step. The result is exactly the { subject, html, text } the notifications mail channel expects.

Tip
User content is HTML-escaped and action URLs are validated (http/https only) — no injection. Compose it with the notifications module's toMail() to send across channels from one Notification.

Compose an email to see the HTML preview and the plaintext version.

src/app/examples/mail/page.tsxTSX
import { renderMailable } from "@bext-stack/framework/mail";

const msg = renderMailable({
  subject: "Your receipt",
  greeting: "Hi Ada,",
  intro: ["Thanks for your order — here is your receipt."],
  action: { text: "View receipt", url: "https://app/receipt/42" },
  salutation: "— The Shop",
  brand: { name: "Shop", color: "#16a34a" },
});
// msg: { subject, html, text } — the shape notifications' toMail() wants:

const Receipt = {
  via: () => ["mail"],
  toMail: (u) => renderMailable({ subject: "Receipt", greeting: `Hi ${u.name},`, /* … */ }),
};