How to Send E-Mail Using NodeMailer and React Email in Next.js

How to Send E-Mail Using NodeMailer and React Email in Next.js

Posted by

kamlesh paul

on

Jan 3, 2025

5 min read

Last updated on : Jan 18, 2025

156 views

Table of contents

Introduction to NodeMailer and React Email

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.

Setting Up Your Next.js Project

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-app

Installing NodeMailer and React Email

To 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/nodemailer
  • NodeMailer: Manages email transport and delivery.
  • @react-email/components: Provides pre-built React components for designing and rendering email templates.

With these libraries in place, you’re ready to build email-sending logic and design templates directly in your Next.js application!

Configuring NodeMailer

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.

Creating the Email Configuration

server/email.ts
"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,
  });
};

Set Up Environment Variables

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-password

Replace the values with your SMTP server details.

How It Works

  • The getTransporter function initializes and reuses a single NodeMailer transporter instance for sending emails.
  • The sendEmail function takes in the recipient’s email address, subject, and a React component to render as the email body.
  • It uses 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!

Creating Email Templates with React Email

React Email simplifies building email templates with React components. Let’s create a basic template for testing purposes.

Create a Test Email Template

Create a file named TestEmail.tsx in a components/emails folder:

TestEmail.tsx
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;

Integrating React Email Components in the Frontend

To trigger email sending via the frontend, integrate React Email with a server action.

Frontend Code

Create a simple form to send a test email.

app/page.tsx
"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 items-center justify-center h-screen gap-10">
      <button
        disabled={loading}
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        onClick={handleSendEmail}
      >
        {loading ? 'Sending...' : 'Send Email'}
      </button>
      <p className="text-center">{status}</p>
    </div>
  );
}
 

Testing Email Functionality

Setting Up the Server Action

Create test-email.action.ts

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
    }),
  });
};
 

Testing

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.

  1. Start the Next.js development server: npm run dev.
  2. Visit the page with the form and click the "Send Email" button.
  3. Log in to Mailtrap to inspect the sent email.

This process ensures your email-sending functionality is fully operational!

Get updates directly to your inbox.

Join 500+ developers getting updates on Laravel & Next.js tips. No spam,
unsubscribe anytime.


Share this article:

156 views