Features

Email Service

Configure and use the email service with Resend and React Email templates.

Overview

Raypx uses Resend as the primary email provider with React Email for templating. The @raypx/email package provides a unified interface for sending emails with pre-built templates.

Features

  • Resend Integration: Modern email API with excellent deliverability
  • React Email Templates: Build emails with React components
  • Nodemailer Fallback: SMTP support for development or alternative providers
  • Preview Server: Local development server for testing emails
  • Type-Safe: Full TypeScript support for all email operations

Configuration

Environment Variables

Add the following to your .env file:

# ===== Email Configuration =====
# Primary: Resend (recommended for production)
RESEND_API_KEY=re_xxxxxxxxxxxxx
RESEND_FROM=noreply@yourdomain.com

# Optional: Nodemailer (for SMTP fallback or development)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-username
SMTP_PASS=your-password
SMTP_FROM=noreply@yourdomain.com

Getting Your Resend API Key

  1. Sign up for a Resend account
  2. Verify your domain in the dashboard
  3. Go to API Keys and create a new key
  4. Copy the API key to your .env file

Quick Start

Sending an Email

import { sendEmail } from "@raypx/email";
import { WelcomeEmail } from "@raypx/email/templates";

await sendEmail({
  to: "user@example.com",
  subject: "Welcome to Raypx!",
  react: WelcomeEmail({ name: "John" }),
});

Using Pre-built Templates

The @raypx/email package includes several pre-built templates:

import { sendEmail } from "@raypx/email";
import {
  WelcomeEmail,
  PasswordResetEmail,
  MagicLinkEmail,
  VerificationEmail,
} from "@raypx/email/templates";

// Welcome email
await sendEmail({
  to: "user@example.com",
  subject: "Welcome!",
  react: WelcomeEmail({
    name: "John",
    loginUrl: "https://yourdomain.com/login",
  }),
});

// Password reset
await sendEmail({
  to: "user@example.com",
  subject: "Reset Your Password",
  react: PasswordResetEmail({
    name: "John",
    resetUrl: "https://yourdomain.com/reset?token=xxx",
  }),
});

// Magic link
await sendEmail({
  to: "user@example.com",
  subject: "Sign in to Raypx",
  react: MagicLinkEmail({
    name: "John",
    magicLinkUrl: "https://yourdomain.com/auth/magic-link?token=xxx",
  }),
});

Email Preview Server

During development, use the email preview server to test emails without sending them.

Start Preview Server

pnpm dev:email
# or
pnpm --filter @raypx/email dev

The preview server runs at http://localhost:3003 by default.

Preview Features

  • Live Preview: See emails rendered in real-time
  • Hot Reload: Changes to templates update instantly
  • Multiple Views: Desktop, mobile, and plain text previews
  • Send Test: Send test emails to yourself

Creating Custom Templates

Template Structure

Create templates using React Email components:

// packages/email/templates/custom-email.tsx
import {
  Body,
  Container,
  Head,
  Heading,
  Html,
  Link,
  Paragraph,
  Text,
} from "@react-email/components";

interface CustomEmailProps {
  name: string;
  actionUrl: string;
}

export function CustomEmail({ name, actionUrl }: CustomEmailProps) {
  return (
    <Html>
      <Head />
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>Hello {name}!</Heading>
          <Paragraph style={paragraph}>
            This is a custom email template.
          </Paragraph>
          <Link href={actionUrl} style={link}>
            Click here
          </Link>
          <Text style={footer}>
            © {new Date().getFullYear()} Raypx. All rights reserved.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

const main = {
  backgroundColor: "#ffffff",
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
};

const container = {
  margin: "0 auto",
  padding: "20px 0 48px",
  maxWidth: "580px",
};

const h1 = {
  color: "#1a1a1a",
  fontSize: "24px",
  fontWeight: "600" as const,
  margin: "0 0 20px",
};

const paragraph = {
  color: "#374151",
  fontSize: "16px",
  lineHeight: "24px",
  margin: "0 0 20px",
};

const link = {
  color: "#2563eb",
  textDecoration: "underline",
};

const footer = {
  color: "#8898aa",
  fontSize: "12px",
  marginTop: "24px",
};

export default CustomEmail;

Export Template

Add your template to the package exports:

// packages/email/templates/index.ts
export { CustomEmail } from "./custom-email";

Available Templates

TemplateDescriptionProps
WelcomeEmailWelcome new usersname, loginUrl
PasswordResetEmailPassword reset linkname, resetUrl
MagicLinkEmailMagic link authenticationname, magicLinkUrl
VerificationEmailEmail verificationname, verificationUrl

Integration with Auth

The email service integrates with Better Auth for authentication emails:

// packages/auth/src/server/auth.ts
import { sendEmail } from "@raypx/email";
import { MagicLinkEmail, VerificationEmail } from "@raypx/email/templates";

export const auth = betterAuth({
  // ... other config
  emailVerification: {
    sendVerificationEmail: async ({ user, url }) => {
      await sendEmail({
        to: user.email,
        subject: "Verify your email",
        react: VerificationEmail({
          name: user.name,
          verificationUrl: url,
        }),
      });
    },
  },
  magicLink: {
    sendMagicLink: async ({ email, url }) => {
      await sendEmail({
        to: email,
        subject: "Sign in to Raypx",
        react: MagicLinkEmail({
          name: email,
          magicLinkUrl: url,
        }),
      });
    },
  },
});

Best Practices

Email Content

  1. Clear Subject Lines: Keep subjects concise and descriptive
  2. Personalization: Use the recipient's name when available
  3. Call to Action: Include clear, prominent action buttons
  4. Plain Text: Always provide a plain text version
  5. Unsubscribe: Include unsubscribe links for marketing emails

Deliverability

  1. Verify Domain: Complete domain verification in Resend
  2. SPF/DKIM/DMARC: Configure DNS records properly
  3. Warm Up IP: Start with low volumes and increase gradually
  4. Monitor Bounces: Track and handle bounced emails
  5. Avoid Spam Triggers: Don't use spammy words or excessive caps

Development

  1. Use Preview Server: Test emails locally before sending
  2. Test Multiple Clients: Check rendering in different email clients
  3. Responsive Design: Ensure emails work on mobile devices
  4. Keep Templates Simple: Complex layouts may break in some clients

Troubleshooting

Email Not Sending

  1. Check API Key: Verify RESEND_API_KEY is correct
  2. Check From Address: Must use a verified domain
  3. Check Logs: Look for error messages in server logs
  4. Test Connection: Use Resend dashboard to send test email

Emails Going to Spam

  1. Verify Domain: Complete domain verification
  2. Check DNS Records: Ensure SPF, DKIM, DMARC are configured
  3. Monitor Reputation: Check sender reputation in Resend dashboard
  4. Review Content: Avoid spam trigger words

Template Not Rendering

  1. Check Imports: Ensure all components are imported correctly
  2. Check Props: Verify all required props are provided
  3. Use Preview: Test in email preview server
  4. Check Console: Look for React errors

On this page