Core Setup

Email

Configure Nodemailer, Resend, or Postmark for transactional emails. Customize templates and preview them locally.

MoveFast uses React Email for beautiful, type-safe email templates. Your variant comes with one email provider pre-configured:

  • Nodemailer - Send via any SMTP server (Gmail, AWS SES, your own server)
  • Resend - Modern email API built for developers
  • Postmark - Reliable transactional email with great deliverability

Nodemailer Setup (SMTP)

Nodemailer sends emails through any SMTP server. This is the most flexible option.

Environment Variables

env
SMTP_HOST=smtp.gmail.com
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
EMAIL_FROM_EMAIL=noreply@yourdomain.com
EMAIL_FROM_NAME=MoveFast

Common SMTP Providers

Gmail:

  • Host: smtp.gmail.com
  • Use an App Password (not your regular password)

AWS SES:

  • Host: email-smtp.us-east-1.amazonaws.com
  • Use IAM SMTP credentials

Custom SMTP:

  • Use whatever host, username, and password your provider gives you

Resend Setup

Resend is a modern email API with a generous free tier.

Environment Variables

env
RESEND_API_KEY=re_xxxxxxxxx
EMAIL_FROM_EMAIL=noreply@yourdomain.com
EMAIL_FROM_NAME=MoveFast

Setup Steps

  1. Create an account at resend.com
  2. Verify your sending domain (add DNS records)
  3. Generate an API key
  4. Set EMAIL_FROM_EMAIL to an address on your verified domain

Postmark Setup

Postmark is known for excellent delivery rates and fast delivery times.

Environment Variables

env
POSTMARK_API_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
EMAIL_FROM_EMAIL=noreply@yourdomain.com
EMAIL_FROM_NAME=MoveFast

Setup Steps

  1. Create an account at postmarkapp.com
  2. Verify your sending domain or email address
  3. Get your server API token from Server > API Tokens
  4. Set EMAIL_FROM_EMAIL to your verified sender address

Included Email Templates

MoveFast ships with 7 ready-to-use email templates in the emails/ folder:

TemplateWhen it is sent
MagicLinkLoginEmailUser requests a magic link to sign in
AdminNewUserSignUpEmailA new user signs up (sent to admin)
ContactFormNotificationEmailSomeone submits the contact form (sent to admin)
UserInvitationEmailAdmin invites a user to the platform
WaitingListWelcomeEmailUser joins the waitlist
WaitingListLaunchEmailAdmin sends launch announcement to waitlist
WaitingListReminderEmailAdmin sends reminder to waitlist users

All templates use shared components (EmailHeader, EmailFooter) for consistent branding.


Preview Emails Locally

React Email includes a dev server that lets you see your templates in the browser:

bash
npm run email:dev

Open http://localhost:3001 to browse and preview all templates with live reloading.


Customizing Templates

Templates are React components in the emails/ folder. Here is a simplified example:

tsx
// emails/WaitingListWelcomeEmail.tsx
import { EmailHeader } from "./components/EmailHeader";
import { EmailFooter } from "./components/EmailFooter";
import { Html, Body, Text } from "@react-email/components";
 
interface Props {
    email: string;
}
 
export default function WaitingListWelcomeEmail({ email }: Props) {
    return (
        <Html>
            <Body>
                <EmailHeader />
                <Text>Thanks for joining our waitlist, {email}!</Text>
                <Text>We will let you know when we launch.</Text>
                <EmailFooter />
            </Body>
        </Html>
    );
}

To customize:

  1. Edit the template components in emails/
  2. Update the shared EmailHeader and EmailFooter for branding
  3. Preview changes at localhost:3001

Sending Emails in Your Code

To send an email from anywhere in the backend:

typescript
import { sendEmailWithTemplate } from "@/lib/email/sendEmail";
import YourTemplate from "@emails/YourTemplate";
 
await sendEmailWithTemplate({
    template: YourTemplate({ name: "John" }),
    subject: "Your Subject Line",
    to: { email: "user@example.com" },
});

The sendEmailWithTemplate function:

  1. Renders the React component to HTML using react-email
  2. Passes it to the configured email provider
  3. Returns the send result (or null if it fails silently)

Adding a New Email Template

  1. Create a new file in emails/:
tsx
// emails/MyNewEmail.tsx
import { EmailHeader } from "./components/EmailHeader";
import { EmailFooter } from "./components/EmailFooter";
 
interface Props {
    userName: string;
    message: string;
}
 
export default function MyNewEmail({ userName, message }: Props) {
    return (
        // Your template JSX
    );
}
  1. Import and use it in your service:
typescript
import MyNewEmail from "@emails/MyNewEmail";
 
await sendEmailWithTemplate({
    template: MyNewEmail({ userName: "Alice", message: "Hello!" }),
    subject: "New notification",
    to: { email: "alice@example.com" },
});
  1. Preview it with npm run email:dev

Tips

  • Always use a verified domain for EMAIL_FROM_EMAIL. Free email addresses (gmail.com, etc.) will get rejected by most providers.
  • In development, you can use Resend's free tier (100 emails/day) or a Gmail app password with Nodemailer.
  • Check spam folders if test emails are not arriving.
  • The sendEmailWithTemplate function swallows errors by default (returns null). This prevents email failures from breaking user-facing flows like sign-up. Errors are still logged.