How to send emails using Next.js 14, Resend and React-Email

Developer with a love for web technologies. Building things with react, next and node.
Search for a command to run...

Developer with a love for web technologies. Building things with react, next and node.
No comments yet. Be the first to comment.
In the fast-paced world of software development, where competition is fierce and innovation is key, having a standout portfolio is not just an advantage—it's a necessity. Your portfolio is more than a collection of projects; it's a visual narrative t...

Next.Js 14 has added a lot of cool features that make development so much easier like: App Router Server Actions Route Handlers Client and Server Components In this article, we will be covering Server Actions. What are Server Actions A Server A...

Next.js provides a solid foundation for building React applications with server-side rendering, while Supabase offers a scalable and easy-to-use backend-as-a-service with PostgreSQL as the database. Since the release of Next.js 13 and then Next.js 14...

This is our first article in the series of Data Structures and Algorithms. In this article, we will discuss the ins and outs of a Singly Linked List. What is a Singly Linked List? A Singly Linked List is a linear data structure that allows us to stor...

Communication with your users is really important and emails are one of the means of communication. Sending emails is really important for applications. These are some of the reasons:
User Onboarding and Account Verification
Password Resets and Account Recovery
Notification and Alerts
Communication and Updates
Marketing and Promotions
Support and Customer Service
In this article, we will dive into sending emails using Next.js 14, Resend and React-Email. We will leverage the latest Next.js features, such as the app directory and server actions.
Before we can start using Resend in our app, first you have to create an account on Resend. After creating the account, you have to verify your domain name and the email address you will be using to send emails.
Once that's done, go to the API Keys page and create a new api key.

Copy an existing API key or click Create Api Key to create a new one.
npx create-next-app@latest
On installation, you'll see the following prompts:
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*
After the prompts, create-next-app will create a folder with your project name and install the required dependencies. Next, we have to install the packages for sending emails.
npm i resend react-email @react-email/components @react-email/render
Let's talk about the packages we just installed:
resend: It is the service that we will be using to send emails
react-email: It allows us to create email templates using React Js.
@react-email/render: For converting react js based templates to an html string.
Let's now create a simple form where the user can enter his name, email and message. And when it is submitted we will send the detail to the entered email.
export default function Form() {
return (
<form>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
<label htmlFor="message">Message</label>
<textarea name="message" id="message" cols={30} rows={10}></textarea>
<button type="submit">Send</button>
</form>
)
}
Now let's create an email template using React Js.
import { Html, Heading, Text } from "@react-email/components"
const EmailTemplate = ({
name,
email,
message
}: {
name: string
email: string
message: string
}) => {
return (
<Html lang="en">
<Heading as="h1">New Form Submission</Heading>
<Text>You just submitted a form. Here are the details:</Text>
<Text>Name: {name}</Text>
<Text>Email: {email}</Text>
<Text>Message: {message}</Text>
</Html>
)
}
export default EmailTemplate
Server action is the latest feature of Next.js 14. It is an asynchronous function that runs on the server. We can use it to handle form submissions and to handle email logic on the server. So when you submit a form the function will start running on a server. In this case, you don't have to create API routes to handle any sensitive logic, like communicating with the database.
Create a file named actions.ts in the src folder (if you have) or the root of your project.
"use server"
import { Resend } from "resend"
import EmailTemplate from "./components/EmailTemplate"
interface State {
error: string | null
success: boolean
}
export const sendEmail = async (prevState: State, formData: FormData) => {
const name = formData.get("name") as string
const email = formData.get("email") as string
const message = formData.get("message") as string
try {
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: "Shahmir <shahmir@mydevpa.ge>",
to: email,
subject: "Form Submission",
react: EmailTemplate({ name, email, message })
})
return {
error: null,
success: true
}
} catch (error) {
console.log(error)
return {
error: (error as Error).message,
success: false
}
}
}
Create a .env.local file in the root of your project and paste the Resend API key you created earlier.
The sendEmail function is a server action. It receives the previous state and the formData, that gives you access to the values of the form. Then it uses resend to send the email to the provided email address. In the from field, make sure to use an email that you verified on your Resend account.
In some cases, the react property might not work and you might receive an error while sending emails. In that case you can convert the React component into an HTML string.
"use server"
import { Resend } from "resend"
import EmailTemplate from "./components/EmailTemplate"
import { render } from "@react-email/render"
interface State {
error: string | null
success: boolean
}
export const sendEmail = async (prevState: State, formData: FormData) => {
const name = formData.get("name") as string
const email = formData.get("email") as string
const message = formData.get("message") as string
try {
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: "Shahmir <shahmir@mydevpa.ge>",
to: email,
subject: "Form Submission",
html: render(EmailTemplate({ name, email, message }))
})
return {
error: null,
success: true
}
} catch (error) {
console.log(error)
return {
error: (error as Error).message,
success: false
}
}
}
Now let's use the server action we created above with our form component.
"use client"
import { sendEmail } from "@/actions"
import { useEffect } from "react"
import { useFormState } from "react-dom"
export default function Form() {
const [sendEmailState, sendEmailAction] = useFormState(sendEmail, {
error: null,
success: false
})
useEffect(() => {
if (sendEmailState.success) {
alert("Email sent!")
}
if (sendEmailState.error) {
alert("Error sending email!")
}
}, [sendEmailState])
return (
<form action={sendEmailAction}>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
<label htmlFor="message">Message</label>
<textarea name="message" id="message" cols={30} rows={10}></textarea>
<button type="submit">Send</button>
</form>
)
}
We are using the useFormState hook. It accepts the action and the initial state and returns the new state and the action function that we can attach with our form.
In the end we added an action property to our form and gave it the server action function.
Now when you submit the form you should receive an email.
This article aimed to help you quickly get started with sending emails. The Resend and React-Email libraries make it so easy to achieve this. To learn more about Resend and React-Email read their official documentation.
MyDevPa.ge allows you to build a portfolio website in minutes. Focus on building great projects and enhancing your skills rather than wasting your time in building a portfolio website from scratch or customizing expensive templates.
MyDevPa.ge handles everything:
Creating a portfolio
SEO
Analytics
Customization
Custom Domain
Contact Form
