Docs/modules/Email

Email

NextShip uses Resend for email delivery and React Email for building templates.

Setup

Environment Variables

RESEND_API_KEY=re_xxx

Resend 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:dev

Opens at http://localhost:3001

Domain Verification

For production, verify your domain in Resend:

  1. Go to Resend dashboard → Domains
  2. Add your domain
  3. Add the DNS records to your domain provider
  4. 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