Loading...
Loading...
> Production-ready email system with React Email templates, queue-based sending, and beautiful transactional emails.
Fabrk uses Resend for email delivery with lightweight HTML templates. The system supports lightweight HTML templates for maximum performance, dual-mode sending (immediate for auth emails, queued for bulk), pre-built templates for common emails, zero-dependency template system, and automatic retry and error handling.
DESC: Add your Resend API key to .env.local
1$RESEND_API_KEY="re_xxxxxxxxxxxx"2$EMAIL_FROM="Your App <noreply@yourdomain.com>"
DESC: Set up your sending domain in Resend dashboard: Go to Resend Dashboard → Domains, add your domain, add the DNS records (SPF, DKIM, DMARC), and verify domain status.
DESC: For queued emails, run the worker
1$npm run email:dev2$# Watches queue and sends emails with auto-restart
Templates are in src/emails/. Pre-built templates include welcome, verify-email, reset-password, purchase-confirmation, and subscription-update.
1// src/emails/welcome-html.ts2export interface WelcomeEmailProps {3 name: string;4 licenseKey: string;5 downloadUrl: string;6}78export function generateWelcomeEmailHTML({9 name,10 licenseKey,11 downloadUrl,12}: WelcomeEmailProps): string {13 return `14<!DOCTYPE html>15<html lang="en">16<head>17 <meta charset="UTF-8">18 <title>Welcome to Fabrk!</title>19</head>20<body style="margin: 0; padding: 0; font-family: system-ui, sans-serif;">21 <div style="max-width: 600px; margin: 0 auto; padding: 40px;">22 <h1>Welcome to Fabrk, ${name}!</h1>23 <p>Thank you for your purchase.</p>2425 <div style="background: #f4f4f5; padding: 20px; border-radius: 8px; margin: 20px 0;">26 <strong>Your License Key:</strong>27 <code style="display: block; font-size: 18px; margin-top: 10px;">${licenseKey}</code>28 </div>2930 <a href="${downloadUrl}" style="background: #000; color: #fff; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">31 Download Now32 </a>33 </div>34</body>35</html>36 `.trim();37}
For immediate delivery (verification, password reset)
1import { sendVerificationEmail, sendResetEmail } from "@/lib/email";23// Send verification email4await sendVerificationEmail({5 to: user.email,6 name: user.name,7 token: verificationToken,8});910// Send password reset email11await sendResetEmail({12 to: user.email,13 name: user.name,14 resetUrl: `${config.app.url}/reset-password?token=${token}`,15});
For non-urgent emails (welcome, receipts)
1import { queueWelcomeEmail, queueConfirmationEmail } from "@/lib/email";23// Queue welcome email4await queueWelcomeEmail({5 to: user.email,6 name: user.name,7 loginUrl: `${config.app.url}/login`,8});910// Queue payment confirmation11await queueConfirmationEmail({12 to: user.email,13 name: user.name,14 amount: payment.amount,15 productName: payment.productName,16 receiptUrl: payment.receiptUrl,17});
Send any HTML content
1import { Resend } from "resend";2import { env } from "@/lib/env";34const resend = new Resend(env.server.RESEND_API_KEY);56await resend.emails.send({7 from: env.server.EMAIL_FROM,8 to: "user@example.com",9 subject: "Your Custom Subject",10 html: "<h1>Hello World</h1><p>This is a custom email.</p>",11});
Send to multiple recipients
1import { Resend } from "resend";2import { env } from "@/lib/env";34const resend = new Resend(env.server.RESEND_API_KEY);56const emails = users.map((user) => ({7 from: env.server.EMAIL_FROM,8 to: user.email,9 subject: "Important Update",10 html: `<h1>Hello ${user.name}</h1>`,11}));1213// Send up to 100 emails in one API call14await resend.batch.send(emails);