Mailables
@bext-stack/framework/mail builds transactional emails the Laravel Mailable
way: you describe a structured spec (greeting, paragraphs, a call-to-action
button, salutation) and renderMailable returns a responsive, inline-styled
HTML email plus a plaintext alternative — no MJML, no build step.
When To Use It#
- Any transactional email that deserves to look designed: receipts, welcome mails, password resets, invoices.
- Whenever you want the HTML and the plaintext versions to stay in sync.
Rendering#
import { renderMailable } from "@bext-stack/framework/mail";
const msg = renderMailable({
subject: "Your receipt",
greeting: "Hi Ada,",
intro: ["Thanks for your order — here's your receipt."],
action: { text: "View receipt", url: "https://app/receipt/42" },
outro: ["If you didn't make this purchase, contact support."],
salutation: "— The Shop",
brand: { name: "Shop", color: "#16a34a", footer: "© Shop 2026" },
});
// msg: { subject, html, text }
The result is exactly the { subject, html, text } shape everything downstream
wants — pass it to the SDK email endpoint, or return it from a Notification's
toMail:
import { renderMailable } from "@bext-stack/framework/mail";
const Receipt = {
via: () => ["mail"],
toMail: (u) => renderMailable({ subject: "Receipt", greeting: `Hi ${u.name},`, /* … */ }),
};
Spec#
| Field | Purpose |
|---|---|
subject |
the email subject |
greeting |
opening line ("Hi Ada,") |
intro[] |
paragraphs before the button |
action |
one CTA { text, url } (a styled button) |
outro[] |
paragraphs after the button |
salutation |
closing line |
brand |
{ name?, color?, footer? } — header + accent + footer |
Safety#
User content is HTML-escaped in the HTML output, action URLs are validated
to http(s) (a javascript: URL becomes #), and the brand accent color is
validated to a hex value — so a mailable built from user input can't inject
markup or scripts into the email.
Try It#
The live mailables demo composes an email
from a form and shows both the rendered HTML preview and the plaintext version.
Source in sites/demo/src/app/examples/mail/page.tsx.
See Also#
- Notifications — deliver the mailable across channels.
- Mailer — the Rust email capability underneath.
- Application Toolkit — the rest of the TypeScript app layer.