Operate in Production
Transactional email with Nodemailer — SMTP, console adapter, and email templates.
QUESTPIE supports sending transactional emails with typed templates.
Configuration
questpie.config.ts
import { SmtpAdapter, ConsoleAdapter, runtimeConfig } from "questpie";
export default runtimeConfig({
email: {
adapter:
process.env.NODE_ENV === "development"
? new ConsoleAdapter({ logHtml: false })
: new SmtpAdapter({
transport: {
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT || "587"),
secure: true,
},
}),
},
});Email Templates
Define templates in emails/:
emails/appointment-confirmation.ts
import { email } from "questpie";
import z from "zod";
export default email({
name: "appointmentConfirmation",
schema: z.object({
customerName: z.string(),
barberName: z.string(),
serviceName: z.string(),
scheduledAt: z.string(),
}),
handler: ({ input }) => ({
subject: "Appointment Confirmed",
html: `
<h1>Hi ${input.customerName}!</h1>
<p>Your appointment has been confirmed.</p>
<p><strong>Barber:</strong> ${input.barberName}</p>
<p><strong>Service:</strong> ${input.serviceName}</p>
<p><strong>When:</strong> ${input.scheduledAt}</p>
`,
}),
});Sending Emails
From jobs, hooks, or routes via the email context:
handler: async ({ email }) => {
await email.sendTemplate({
template: "appointmentConfirmation",
input: {
customerName: "John",
barberName: "Mike",
serviceName: "Haircut",
scheduledAt: "2025-03-15 10:00",
},
to: "john@example.com",
});
};Adapters
| Adapter | Description |
|---|---|
SmtpAdapter | Send via SMTP (production) |
ConsoleAdapter | Log to console (development) |