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
-
Create Resend Account:
- Visit resend.com
- Create an account and verify your domain
-
Get API Key:
- Go to API Keys section
- Create a new API key with send permissions
- Add to your environment variables
-
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:
Template | Description | Context Props |
---|---|---|
forgotPassword | Password reset | name: string , url: string |
emailVerification | Email verification | name: string , url: string |
newsletterSignup | Newsletter confirmation | name: string , unsubscribeUrl: string |
contactForm | Contact form notification | name: 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
};
🔗 Related Resources
🎯 Next Steps
Now that you understand the email system, explore these related features: