February 12, 2025
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.
If you donβt already have a Next.js project, create one:
bashnpx create-next-app@latest my-next-email-app
cd my-next-email-app
Then, install dependencies:
bashnpm install @react-email/components @react-email/render
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.
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.
To send emails, we'll use Resend, an email service that supports React Email.
bashnpm install resend
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({ : , error }), {
: ,
});
}
}
This API route:
email and nameTo 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.");
}
();
};
(
);
}
Now visit http://localhost:3000/send-email, enter an email and name, and click Send Email.
You've now set up React Email in a Next.js project! π
β 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.