NextShip uses Resend for email delivery and React Email for building templates.
Setup
Environment Variables
RESEND_API_KEY=re_xxxResend Client
// src/lib/email.ts
import { Resend } from "resend";
export const resend = new Resend(process.env.RESEND_API_KEY);Creating Email Templates
Email templates are React components in emails/:
// emails/welcome.tsx
import {
Html,
Head,
Body,
Container,
Section,
Text,
Button,
Hr,
} from "@react-email/components";
interface WelcomeEmailProps {
name: string;
loginUrl: string;
}
export function WelcomeEmail({ name, loginUrl }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Body style={main}>
<Container style={container}>
<Section>
<Text style={heading}>Welcome to NextShip!</Text>
<Text style={paragraph}>
Hi {name}, thanks for signing up. We're excited to have you!
</Text>
<Button style={button} href={loginUrl}>
Go to Dashboard
</Button>
<Hr style={hr} />
<Text style={footer}>
© 2024 NextShip. All rights reserved.
</Text>
</Section>
</Container>
</Body>
</Html>
);
}
const main = {
backgroundColor: "#f6f9fc",
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
};
const container = {
backgroundColor: "#ffffff",
margin: "0 auto",
padding: "40px 20px",
borderRadius: "8px",
};
const heading = {
fontSize: "24px",
fontWeight: "bold",
marginBottom: "20px",
};
const paragraph = {
fontSize: "16px",
lineHeight: "26px",
marginBottom: "20px",
};
const button = {
backgroundColor: "#000000",
color: "#ffffff",
padding: "12px 24px",
borderRadius: "6px",
textDecoration: "none",
};
const hr = {
borderColor: "#e6ebf1",
margin: "30px 0",
};
const footer = {
color: "#8898aa",
fontSize: "12px",
};Sending Emails
import { resend } from "@/lib/email";
import { WelcomeEmail } from "@/emails/welcome";
export async function sendWelcomeEmail(to: string, name: string) {
await resend.emails.send({
from: "NextShip <noreply@yourdomain.com>",
to,
subject: "Welcome to NextShip!",
react: WelcomeEmail({
name,
loginUrl: `${process.env.NEXT_PUBLIC_APP_URL}/login`
}),
});
}Common Email Templates
Password Reset
export function PasswordResetEmail({ resetUrl }: { resetUrl: string }) {
return (
<Html>
<Body style={main}>
<Container style={container}>
<Text style={heading}>Reset Your Password</Text>
<Text style={paragraph}>
Click the button below to reset your password. This link expires in 1 hour.
</Text>
<Button style={button} href={resetUrl}>
Reset Password
</Button>
</Container>
</Body>
</Html>
);
}Invoice
export function InvoiceEmail({
amount,
invoiceUrl
}: {
amount: string;
invoiceUrl: string;
}) {
return (
<Html>
<Body style={main}>
<Container style={container}>
<Text style={heading}>Payment Received</Text>
<Text style={paragraph}>
Thank you for your payment of {amount}.
</Text>
<Button style={button} href={invoiceUrl}>
View Invoice
</Button>
</Container>
</Body>
</Html>
);
}Preview Emails
React Email provides a preview server:
pnpm email:devOpens at http://localhost:3001
Domain Verification
For production, verify your domain in Resend:
- Go to Resend dashboard → Domains
- Add your domain
- Add the DNS records to your domain provider
- Wait for verification (usually minutes)
Best Practices
- Use a verified domain for production
- Include unsubscribe links for marketing emails
- Test emails in different email clients
- Keep templates simple and mobile-friendly