LogoNEXTDEVKIT Docs

Email

Learn how to send emails and manage newsletters with React Email in NEXTDEVKIT

NEXTDEVKIT includes a powerful email system built with React Email and Resend provider, providing beautiful, responsive email templates with internationalization support perfect for transactional emails, newsletters, and user communications.

🏗️ Email System Architecture

NEXTDEVKIT's email system is structured as follows:

src/
├── mail/
│   ├── index.ts                    # Main email sending functions
│   ├── types.ts                    # Email interfaces and types
│   ├── actions.ts                  # Newsletter server actions
│   ├── templates/
│   │   ├── index.ts               # Template registry
│   │   ├── forgot-password.tsx    # Password reset template
│   │   ├── email-verification.tsx # Email verification template
│   │   ├── newsletter-signup.tsx  # Newsletter signup template
│   │   └── contact-form.tsx       # Contact form template
│   ├── providers/
│   │   ├── index.ts               # Provider registry
│   │   └── resend.ts              # Resend provider
│   └── components/
│       ├── layout.tsx             # Email layout component
│       └── email-button.tsx       # Email button component
├── config/
│   └── index.ts                   # Email configuration
└── messages/
    ├── en.json                    # English email translations
    └── zh.json                    # Chinese email translations

⚙️ Email Configuration

App Configuration

Email settings are configured in src/config/index.ts:

export const appConfig = {
  mail: {
    provider: "resend",              // Email provider
    from: "noreply@nextdevkit.com",  // Default sender address
    contact: "contact@nextdevkit.com", // Contact email address
  },
  // ... other config
} as const;

Environment Variables

Set up the required environment variables:

# For Resend
RESEND_API_KEY=re_your_resend_api_key
RESEND_AUDIENCE_ID=your_audience_id  # For newsletter

Provider Setup

Resend Setup

  1. Create Resend Account:

    • Visit resend.com
    • Create an account and verify your domain
  2. Get API Key:

    • Go to API Keys section
    • Create a new API key with send permissions
    • Add to your environment variables
  3. Newsletter Setup (optional):

    • Create an audience in Resend
    • Get the audience ID for newsletter functionality

📧 Email Templates

Available Templates

NEXTDEVKIT includes pre-built email templates:

TemplateDescriptionContext Props
forgotPasswordPassword resetname: string, url: string
emailVerificationEmail verificationname: string, url: string
newsletterSignupNewsletter confirmationname: string, unsubscribeUrl: string
contactFormContact form notificationname: string, email: string, message: string

Template Structure

Each template is a React component with internationalization support:

import { Layout } from "@/mail/components/layout";
import { EmailButton } from "@/mail/components/email-button";
import type { i18nEmailProps } from "@/mail/types";

interface WelcomeEmailProps extends i18nEmailProps {
  name: string;
}

export function Welcome({ name, locale, messages }: WelcomeEmailProps) {
  const t = createTranslator({
    locale,
    messages,
    namespace: "mail.welcome",
  });

  return (
    <Layout>
      <Text>{t("greeting", { name })}</Text>
      <Text>{t("body")}</Text>
      <EmailButton href="https://nextdevkit.com/docs">
        {t("getStarted")}
      </EmailButton>
    </Layout>
  );
}

Template Registry

Templates are registered in src/mail/templates/index.ts:

export const mailTemplates = {
  forgotPassword: ForgotPassword,
  newsletterSignup: NewsletterSignup,
  emailVerification: EmailVerification,
  contactForm: ContactForm,
} as const;

export type TemplateKey = keyof typeof mailTemplates;

📤 Sending Emails

Basic Email Sending

Use the sendEmail function to send emails:

import { sendEmail } from "@/mail";

// Send using a template
await sendEmail({
  to: "user@example.com",
  templateKey: "forgotPassword",
  context: {
    name: "John Doe",
    url: "https://example.com/reset-password",
  },
  locale: "en", // Optional, defaults to config default
});

// Send raw HTML email
await sendEmail({
  to: "user@example.com",
  subject: "Welcome to NEXTDEVKIT",
  html: "<h1>Welcome!</h1><p>Thank you for joining us.</p>",
  text: "Welcome! Thank you for joining us.",
});

Server Actions Example

"use server";

import { sendEmail } from "@/mail";
import { getSession } from "@/lib/auth/server";

export async function sendResetPasswordEmail(resetUrl: string) {
  const session = await getSession();
  
  if (!session?.user) {
    throw new Error("Not authenticated");
  }

  const success = await sendEmail({
    to: session.user.email,
    templateKey: "forgotPassword",
    context: {
      name: session.user.name || "User",
      url: resetUrl,
    },
  });

  if (!success) {
    throw new Error("Failed to send reset password email");
  }
}

📰 Newsletter Management

Newsletter Actions

NEXTDEVKIT provides server actions for newsletter management:

import { 
  subscribeToNewsletter, 
  unsubscribeFromNewsletter, 
  isSubscribedToNewsletter 
} from "@/mail/actions";

// Subscribe to newsletter
await subscribeToNewsletter({ email: "user@example.com" });

// Unsubscribe from newsletter
await unsubscribeFromNewsletter({ email: "user@example.com" });

// Check subscription status
const isSubscribed = await isSubscribedToNewsletter({ email: "user@example.com" });

🌐 Internationalization

Email Translations

Email translations are stored in message files:

English (messages/en.json):

{
  "mail": {
    "forgotPassword": {
      "subject": "Reset your password",
      "greeting": "Hi {name}!",
      "body": "Click the button below to reset your password.",
      "resetPassword": "Reset Password"
    },
    "emailVerification": {
      "subject": "Verify your email",
      "greeting": "Hi {name}!",
      "body": "Click the button below to verify your email address.",
      "verifyEmail": "Verify Email"
    }
  }
}

Chinese (messages/zh.json):

{
  "mail": {
    "forgotPassword": {
      "subject": "重置密码",
      "greeting": "你好 {name}!",
      "body": "点击下面的按钮重置你的密码。",
      "resetPassword": "重置密码"
    },
    "emailVerification": {
      "subject": "验证邮箱",
      "greeting": "你好 {name}!",
      "body": "点击下面的按钮验证你的邮箱地址。",
      "verifyEmail": "验证邮箱"
    }
  }
}

Localized Email Sending

// Send localized email
await sendEmail({
  to: "user@example.com",
  templateKey: "forgotPassword",
  context: {
    name: "张三",
    url: "https://example.com/reset-password",
  },
  locale: "zh", // Chinese locale
});

🔧 Creating Custom Templates

1. Create Template Component

import { Text } from "@react-email/components";
import { createTranslator } from "use-intl/core";
import { Layout } from "@/mail/components/layout";
import { EmailButton } from "@/mail/components/email-button";
import type { i18nEmailProps } from "@/mail/types";

interface CustomTemplateProps extends i18nEmailProps {
  userName: string;
  actionUrl: string;
}

export function CustomTemplate({ 
  userName, 
  actionUrl, 
  locale, 
  messages 
}: CustomTemplateProps) {
  const t = createTranslator({
    locale,
    messages,
    namespace: "mail.customTemplate",
  });

  return (
    <Layout>
      <Text>{t("greeting", { name: userName })}</Text>
      <Text>{t("body")}</Text>
      <EmailButton href={actionUrl}>
        {t("action")}
      </EmailButton>
    </Layout>
  );
}

2. Register Template

import { CustomTemplate } from "./custom-template";

export const mailTemplates = {
  // ... existing templates
  customTemplate: CustomTemplate,
} as const;

3. Add Translations

// messages/en.json
{
  "mail": {
    "customTemplate": {
      "subject": "Custom Email Subject",
      "greeting": "Hello {name}!",
      "body": "This is a custom email template.",
      "action": "Take Action"
    }
  }
}

4. Use Template

await sendEmail({
  to: "user@example.com",
  templateKey: "customTemplate",
  context: {
    userName: "John Doe",
    actionUrl: "https://nextdevkit.com/action",
  },
});

🔌 Custom Email Providers

Create Custom Provider

import type { MailProvider, SendParams } from "@/mail/types";

export class CustomMailProvider implements MailProvider {
  private apiKey: string;

  constructor() {
    this.apiKey = process.env.CUSTOM_MAIL_API_KEY!;
  }

  async sendEmail(params: SendParams): Promise<void> {
    const response = await fetch("https://api.customprovider.com/send", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        to: params.to,
        subject: params.subject,
        html: params.html,
        text: params.text,
      }),
    });

    if (!response.ok) {
      throw new Error("Failed to send email");
    }
  }

  async subscribe(email: string): Promise<void> {
    // Implementation for subscribing to newsletter
  }

  async unsubscribe(email: string): Promise<void> {
    // Implementation for unsubscribing from newsletter
  }

  async isSubscribed(email: string): Promise<boolean> {
    // Implementation for checking subscription status
    return false;
  }
}

Register Provider

import { CustomMailProvider } from "./custom-provider";

const providers = {
  resend: ResendMailProvider,
  custom: CustomMailProvider, // Add custom provider
} as const;

Update Configuration

export const appConfig = {
  mail: {
    provider: "custom", // Use custom provider
    from: "noreply@nextdevkit.com",
    contact: "contact@nextdevkit.com",
  },
  // ... other config
};

🎯 Next Steps

Now that you understand the email system, explore these related features: