
Learn to send emails in Next.js using NodeMailer and React Email. Build templates, configure SMTP, and integrate email functionality with step-by-step guidance.
Sending emails is a common feature in modern web applications, and tools like NodeMailer and React Email make it simple and efficient. NodeMailer handles backend email delivery, while React Email helps you create beautiful, reusable email templates with React components. Together, they provide a powerful solution for managing emails in a Next.js application. Let’s explore how to use them!
For those specifically looking to test email functionality without sending actual emails to user inboxes, I recommend reading my detailed article on Email Testing with Mailtrap in Next.js.
Before we dive into email functionality, let’s get your Next.js project ready. Start by creating a new Next.js application if you don’t already have one:
npx create-next-app@latest my-nextjs-email-app
cd my-nextjs-email-appTo enable email functionality, you need to install NodeMailer for handling email delivery and React Email for creating templates. Run the following command in your project directory to install them:
pnpm add nodemailer @react-email/components
pnpm add -D @types/nodemailerWith these libraries in place, you’re ready to build email-sending logic and design templates directly in your Next.js application!
To configure NodeMailer in your Next.js project, create a file named email.ts inside the server directory. This file will contain the logic for sending emails.
Note: You can also configure and test your SMTP credentials more efficiently using Mailtrap. Check out the Mailtrap setup guide for step-by-step instructions.
"server-only";
import { ADMIN_EMAIL } from '@/config/consts.server.';
import { render } from '@react-email/components';
import nodemailer, { Transporter } from 'nodemailer';
import SMTPTransport from 'nodemailer/lib/smtp-transport';
import { ReactElement } from 'react';
let transporter: Transporter<SMTPTransport.SentMessageInfo> | null = null;
const getTransporter = (): Transporter<SMTPTransport.SentMessageInfo> => {
if (!transporter) {
transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST as string,
port: parseInt(process.env.EMAIL_PORT as string),
secure: false, // Set to true for TLS
auth: {
user: process.env.EMAIL_USER as string,
pass: process.env.EMAIL_PASS as string,
},
} as SMTPTransport.Options);
}
return transporter;
};
export const sendEmail = async ({
to,
subject,
component,
}: {
to: string;
subject: string;
component: ReactElement;
}) => {
const transport = getTransporter();
const emailHtml = await render(component);
return transport.sendMail({
from: ADMIN_EMAIL,
to: to,
subject: subject,
html: emailHtml,
});
};Add the following environment variables to your .env file:
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USER=your-email@example.com
EMAIL_PASS=your-email-passwordReplace the values with your SMTP server details.
getTransporter function initializes and reuses a single NodeMailer transporter instance for sending emails.sendEmail function takes in the recipient’s email address, subject, and a React component to render as the email body.render from @react-email/components to convert the React component into HTML for the email.With this setup, you’re ready to send beautifully designed emails directly from your Next.js application!
React Email simplifies building email templates with React components. Let’s create a basic template for testing purposes.
Create a file named TestEmail.tsx in a components/emails folder:
import React from 'react';
import { Html, Head, Body, Container, Heading, Text } from '@react-email/components';
const TestEmail = ({
name
}:{
name: string;
}) => {
return (
<Html>
<Head />
<Body style={{ fontFamily: 'Arial, sans-serif', padding: '20px', backgroundColor: '#f9f9f9' }}>
<Container style={{ backgroundColor: '#ffffff', padding: '20px', borderRadius: '8px' }}>
<Heading style={{ fontSize: '20px', marginBottom: '10px' }}>Hello {name},</Heading>
<Text>This is a test email to confirm everything is working perfectly.</Text>
</Container>
</Body>
</Html>
);
};
export default TestEmail;To trigger email sending via the frontend, integrate React Email with a server action.
Create a simple form to send a test email.
"use client";
import { sendTestEmailAction } from "@/server/actions/test-email.action";
import { useState } from "react";
export default function Home() {
const [status, setStatus] = useState('');
const [loading, setLoading] = useState(false);
const handleSendEmail = async () => {
setLoading(true);
const result = await sendTestEmailAction({ name: 'Kamlesh' });
if (result.accepted.length > 0) {
setStatus('Email sent successfully');
} else {
setStatus('Email not sent');
}
setLoading(false);
}
return (
<div className="flex flex-col justify-center items-center gap-10 h-screen">
<button
disabled={loading}
className="bg-blue-500 hover:bg-blue-700 px-4 py-2 rounded font-bold text-white"
onClick={handleSendEmail}
>
{loading ? 'Sending...' : 'Send Email'}
</button>
<p className="text-center">{status}</p>
</div>
);
}
Create test-email.action.ts
"use server";
import { createElement } from 'react';
import { sendEmail } from '../email';
import TestEmail from '@/components/emails/TestEmail';
export const sendTestEmailAction = async ({name}: {name: string}) => {
return await sendEmail({
to: 'recipient@mail.com',
subject: 'Test Email',
component: createElement(TestEmail,{
name: name
}),
});
};
When testing email functionality, it's important to verify that emails are sent and rendered correctly. Using Mailtrap is a safe and efficient way to test your emails without spamming real inboxes. If you're unfamiliar with Mailtrap, refer to the dedicated article: Email Testing with Mailtrap in Next.js.
npm run dev.This process ensures your email-sending functionality is fully operational!