2025-02-12 Web Development, Marketing

How to Use React Email in a Next.js Project

By O. Wolfson

Email templates have traditionally been built using HTML and inline styles, which can be tedious and inconsistent across different email clients. React Email simplifies this by allowing you to build responsive, component-based emails using React.

In this tutorial, you'll learn how to set up React Email in a Next.js 15 project and send emails using Resend.


1. Setting Up Your Next.js Project

If you don’t already have a Next.js project, create one:

bash
npx create-next-app@latest my-next-email-app
cd my-next-email-app

Then, install dependencies:

bash
npm install @react-email/components @react-email/render

2. Creating an Email Template

Inside your Next.js project, create an emails directory and add a file called WelcomeEmail.tsx:

tsx
// emails/WelcomeEmail.tsx
import {
  Html,
  Head,
  Body,
  Container,
  Text,
  Heading,
  Button,
} from "@react-email/components";

export default function WelcomeEmail({ name }: { name: string }) {
  return (
    <Html>
      <Head />
      <Body
        style={{
          fontFamily: "Arial, sans-serif",
          backgroundColor: "#f3f3f3",
          padding: "20px",
        }}
      >
        <Container
          style={{
            backgroundColor: "#fff",
            padding: "20px",
            borderRadius: "5px",
          }}
        >
          <Heading style={{ color: "#333" }}>Welcome, {name}!</Heading>
          <Text>
            We're excited to have you onboard. Click below to get started.
          </Text>
          <Button
            href="https://yourwebsite.com"
            style={{
              backgroundColor: "#007bff",
              color: "#fff",
              padding: "10px 20px",
              textDecoration: "none",
              borderRadius: "5px",
            }}
          >
            Get Started
          </Button>
        </Container>
      </Body>
    </Html>
  );
}

This component defines a simple email layout with a Heading, Text, and a Button.


3. Previewing the Email in the Browser

To test your email template, create a preview route in Next.js 15.

In app/email-preview/page.tsx, add:

tsx
// app/email-preview/page.tsx
import { render } from "@react-email/render";
import WelcomeEmail from "@/emails/WelcomeEmail";

export default async function EmailPreview() {
  const html = await render(<WelcomeEmail name="John Doe" />);

  // biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

Now, visit http://localhost:3000/email-preview to see the email rendered in the browser.


4. Sending the Email with Resend

To send emails, we'll use Resend, an email service that supports React Email.

4.1 Install Resend SDK

bash
npm install resend

4.2 Get Your API Key

  1. Sign up at Resend
  2. Create an API key from the dashboard

4.3 Create a Server Action for Sending Emails

Next, create a server action inside app/api/send-email/route.ts:

tsx
// app/api/send-email/route.ts
import { Resend } from "resend";
import WelcomeEmail from "@/emails/WelcomeEmail";
import { render } from "@react-email/render";

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(req: Request) {
  const { email, name } = await req.json();

  const html = render(<WelcomeEmail name={name} />);

  try {
    const response = await resend.emails.send({
      from: "Your Name <hello@yourdomain.com>",
      to: email,
      subject: "Welcome to Our Platform!",
      html,
    });

    return new Response(JSON.stringify({ success: true, data: response }), {
      status: 200,
    });
  } catch (error) {
    return new Response(JSON.stringify({ success: false, error }), {
      status: 500,
    });
  }
}

This API route:

  • Accepts a POST request with email and name
  • Renders the React Email template as HTML
  • Sends it via Resend

5. Triggering the Email from the Frontend

To send an email from your Next.js app, create a simple form:

tsx
// app/send-email/page.tsx
"use client";

import { useState } from "react";

export default function SendEmailPage() {
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [loading, setLoading] = useState(false);
  const [message, setMessage] = useState("");

  const sendEmail = async () => {
    setLoading(true);
    setMessage("");

    try {
      const res = await fetch("/api/send-email", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, name }),
      });

      const data = await res.json();
      if (data.success) {
        setMessage("Email sent successfully!");
      } else {
        setMessage("Failed to send email.");
      }
    } catch (error) {
      setMessage("An error occurred.");
    }

    setLoading(false);
  };

  return (
    <div className="max-w-md mx-auto p-4">
      <h1 className="text-xl font-bold mb-4">Send Welcome Email</h1>
      <input
        type="email"
        placeholder="Recipient Email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        className="w-full p-2 border mb-2"
      />
      <input
        type="text"
        placeholder="Recipient Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
        className="w-full p-2 border mb-2"
      />
      <button
        onClick={sendEmail}
        disabled={loading}
        className="bg-blue-500 text-white px-4 py-2"
      >
        {loading ? "Sending..." : "Send Email"}
      </button>
      {message && <p className="mt-2">{message}</p>}
    </div>
  );
}

Now visit http://localhost:3000/send-email, enter an email and name, and click Send Email.


6. Conclusion

You've now set up React Email in a Next.js project! πŸŽ‰

Recap:

βœ” Installed React Email
βœ” Created a WelcomeEmail template
βœ” Previewed the email in the browser
βœ” Set up Resend for sending emails
βœ” Built a server action to send emails
βœ” Created a frontend form to trigger emails

This method ensures emails are maintainable, responsive, and scalable. You can now create more templates and integrate them with transactional emails like password resets, order confirmations, and more.