Emails
Send transactional emails with Mailgun integration.
shipsaas includes a ready-to-use email sender powered by Mailgun via lib/email.ts. Email settings are configured in lib/config.ts.
Setup
1. Create Mailgun Account
- Sign up at app.mailgun.com
- Verify your domain or use the sandbox domain for testing
- Go to Settings → API Security
- Copy your API key
2. Install Dependencies
npm install mailgun.js form-data3. Configure Environment
.env.local
MAILGUN_API_KEY=your-mailgun-api-key4. Configure Email Settings
Update the mailgun section in lib/config.ts:
lib/config.ts
// lib/config.ts → mailgun section
mailgun: {
subdomain: "mg",
fromNoReply: "YourApp <noreply@mg.yourapp.com>",
fromAdmin: "YourApp <admin@mg.yourapp.com>",
supportEmail: "support@yourapp.com",
forwardRepliesTo: "support@yourapp.com",
},Email Sender
The email sender is in lib/email.ts. It lazily loads the Mailgun client and reads configuration from config:
lib/email.ts
Mailgun email sender with sendEmail function and lazy client initialization.
sendEmail Function
import { sendEmail } from "@/lib/email";
// Send a simple email
await sendEmail({
to: "user@example.com",
subject: "Welcome!",
html: "<h1>Hello!</h1><p>Welcome to our app.</p>",
});
// With plain text fallback and reply-to
await sendEmail({
to: "user@example.com",
subject: "Your receipt",
html: "<h1>Payment received</h1>",
text: "Payment received — thank you!",
replyTo: "support@yourapp.com",
});Email Templates
Welcome Email
lib/email-templates.ts
export function getWelcomeEmail(userName: string) {
return `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background: linear-gradient(135deg, #667eea, #764ba2); padding: 30px; border-radius: 10px 10px 0 0; text-align: center;">
<h1 style="color: white; margin: 0;">Welcome!</h1>
</div>
<div style="background: #f9fafb; padding: 30px; border-radius: 0 0 10px 10px;">
<p>Hi <strong>${userName}</strong>,</p>
<p>Thanks for joining! Get started by exploring your dashboard.</p>
<a href="https://yourapp.com/dashboard"
style="background: #667eea; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; display: inline-block;">
Get Started
</a>
</div>
</div>
`;
}Payment Confirmation
export function getPaymentEmail(amount: number, planName: string) {
return `
<h2>Payment Successful!</h2>
<p>Thank you for your payment of <strong>$${amount}</strong>.</p>
<p>Your <strong>${planName}</strong> plan is now active.</p>
`;
}Best Practices
- •Use descriptive subject lines — Clear and actionable
- •Include plain text fallback — Pass both
htmlandtextto sendEmail - •Test with sandbox domain — Mailgun provides a free sandbox for development
- •Handle errors gracefully — The sender logs warnings if Mailgun is not configured
Development tip: If MAILGUN_API_KEY is missing, the app will log a warning but won't crash — emails simply won't be sent.
Ready to send emails! Start engaging with your users through transactional emails and notifications.