Sending emails from your apps shouldn’t be difficult especially if you’re using Resend - the email tool for developers. In this article, we’ll see how to send email using Resend in a step-by-step guide. At the end of this article, you should be able to integrate and send emails easily using Resend.

NB: The source code of this tutorial is available on GitHub!

What’s Resend Email?

Resend, Co-founded by Zeno Rocha, Bu Kinoshita, and Zeh Fernandes, is an email tool for developers to build, test, and deliver transactional emails that will land in users’ inboxes and not spam folders. 

The single idea of creating Resend was to change the way emails are sent, thus making it extremely easy for developers to design email flow and send emails from their apps.

How to send email with Resend API

Prerequisite:


Resend is easy to integrate and works with top languages/frameworks and SMTP support.

For this tutorial, it’s essential to have a little understanding of the following technologies and tools.

  •  Next.js - react.js framework ( You can use Node.js or any language with a custom server)

And we’ll be making use of the following tools;

  • React.email - a tool for building/designing emails with HTML.

  • Resend account ( to get your API key)

  • Custom domain ( to send your email from.)

Getting Started - Understanding the Project:

It’s important to understand what we’ll be building in this tutorial. In this tutorial, we’d build a very simple website that asks for the user’s email and name. Once the user provides their name and email, we’ll send a welcome email to them ( more like a registration page, and welcome on-board email).

Now that we’ve seen what we want to build, it’s now time for the installation and setup. Straight up, we need to install/download the next.js starter pack. This will be a plain JavaScript project.

Getting Started - Set Up :

The first and foremost thing we need to do is to create a Resend.com account. You can use your email and password, or simply log in with the other available methods.

Once you're logged in, you need to create your API key, and set up your domain ( to start sending emails from it ).

Okay! Domain configured, API key generated, what's next...?


The next thing is to install or set up Next.js. Doing this is super easy, most of us already know :)

Open your terminal, and run the following command in the folder where you want. E.g if you want to have a folder named ‘resend_app’  on the Desktop, open your terminal and cd Desktop. Now run the the command:
npx create-next-app@latest

It’d ask you some questions, like the name you like to use for the App,  do you wish to use typescript, if you’d like to use Eslint and TailwindCss( yes please), and if you prefer to use the app over page directory. Complete the on-screen questions and it’ll start the installation. Depending on your internet speed and machine, it might take a few seconds/minutes to complete the installation. 

To be clear, my installation config is as follows:

Once the installation is complete, open the folder in your text editor. If you’re using VS code, you can do cd folder_name and then code . to open the project in VSCode.

Your project installation is complete, now what’s next?

Run npm run dev to spin it up on your browser - if everything goes as planned you should see a screen as follows:

Ok! Our new project is running, it’s time for some editing and actually writing code (The fun part, maybe.). 

To conclude the installation topic, we need to install both react.email, and Resend.


Simply run npm install react-email @react-email/components -E This will install the email.react and give us full access to design some friendly emails!

Run npm install resend if you’re using npm, or yarn add resend if you’re using yarn, or pnpm add resend if you’re using pnpm.

Building signup page

When you visit the project on your browser, you should see a little message at the top that says “Get started by editing src/app/page.tsx”. 

To get started, create a components folder in the src/app directory of the project. Then create a new file with any name of your choice. To make our code easier to read, I’d suggest you use HomePage.tsx

Copy the following code into that newly created file of yours.

"use client";

import { useState } from "react";

export const HomePage = () => {
const [formData, setFormData] = useState({ name: "", email: "" });
const handleFormSubmit = async (e: React.MouseEvent<HTMLElement>) => {

e.preventDefault();
// we’d magic code here

}

return (
<section className="bg-slate-900 h-screen">
<main className=" text-gray-50 flex flex-col items-center justify-between p-24">
<div className="">
<h1 className="text-6xl">Welcome</h1>
<p className="pt-4">Please provide your details to continue.</p>
</div>
<form className="w-full md:w-1/2 mt-20">
<div className="mb-6 ">
<label htmlFor="name" className="text-sm font-medium block mb-2">
Your email*
</label>
<input
type="text"
id="name"
className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="Your Name"
required
value={formData.name}
onChange={(e) =>
setFormData({ ...formData, name: e.target.value })
}
/>
</div>
<div className="mb-6">
<label
htmlFor="email"
className="text-sm font-medium text-gray-100 block mb-2"
>
Your Email*
</label>
<input
type="email"
id="email"
className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
required
value={formData.email}
onChange={(e) =>
setFormData({ ...formData, email: e.target.value })
}
/>
</div>

<div className="w-full flex flex-col items-center ">

<button
onClick={handleFormSubmit}
type="submit"
className="text-white bg-blue-700 font-medium rounded-lg text-lg px-5 py-2.5 text-center"
>
Send Email
</button>
</div>
</form>
</main>
</section>

);
};

Right now, we’ve just added the code that’d ask the user for his/her name and email address, plus we used use-client to turn the component into a client component and useState to keep track of the app’s current state. 

Go back to the page.tsx file in the src/app directory, import the newly created file, and use it as follows:

import * as React from "react";
import { HomePage } from "../components/home";


export default function Home() {
return <HomePage />;
}

Save the file, spin your dev server and if everything goes well, you should see a simple page on your browser asking you to input your name and email as follows.

Building a thank you page:

Now that we have the sign-up page in place, we need to build the thank you page - the page that’s shown when the user sends an email. 

In your components folder, create a new file and name it ThankYou.tsx  then copy the following code into it.

interface ThankyouType {
username: string;
}


export const ThankYouPage = ({ username }: ThankyouType) => {
return (
<section className="bg-slate-900 h-screen">
<main className=" text-gray-50 flex flex-col items-center justify-between p-24">
<div className="text-center">
<h1 className="text-6xl">Thank you!</h1>
<p className="pt-4">We got your email!</p>
<p className="mt-10">
Hi {username}, <br /> we got the email you sent, and we'll happy to
let you know we'd keep in touch!
</p>
</div>
</main>
</section>
);
};

This file or component accepts a string which is the name of the user. We need this to personalize the thank you page.
If you’d like to see how it looks, simply import it into the src/app/pages.tsx file and pass the username as a query over to it.
<ThankYouPage username="Iroro"/>;

You should see:

Clean and neat, right? 🫶🫶

Now our sign-up and thank-you page design is complete. How about writing some code to finally redirect the user to the thank you page after they sign up? Oh, wait! We need to design our email template too isn’t that right?

Building an Email template:

From the installation section of this tutorial, you should have probably installed react.email. If you haven’t, please install it with the following command:

npm install react-email @react-email/components -E


Once the installation is complete, on your components folder, create a new file and name it welcomeEmail.tsx. This file will hold our email template design - what you’d see in your mail app!


Keep in mind that the react.email team has designed some templates for us, and I’m gonna go ahead and edit one of the templates found here.

Copy the following code and paste it into your newly created file:

import {
   Body,
   Button,
   Container,
   Head,
   Heading,
   Hr,
   Html,
   Img,
   Link,
   Preview,
   Section,
   Tailwind,
   Text,
 } from "@react-email/components";
 import * as React from "react";
  interface VercelInviteUserEmailProps {
   username: string;
   email: string;
 }
  export const WelcomeEmail = ({ username, email }: VercelInviteUserEmailProps) => {
   const invitedByUsername = "Iroro Chadere";
   const invitedTwitterLink = "https://twitter.com/iroro_chad";
   const inviteLink = "https://vercel.com/teams/invite/foo";
   const previewText = `${invitedByUsername} has just invited you to test our app`; // what the user sees before clicking on the email.
    return (
     <Html>
       <Head />
       <Preview>{previewText}</Preview>
       <Tailwind>
         <Body className="bg-white my-auto mx-auto font-sans ">
           <Container className="border border-solid border-[#eaeaea] rounded my-8 mx-auto w-[465px] leading-4">
             <Section className="mt-[32px]">
               <Img
                 src="/vercel.svg"
                 width="140"
                 height="80"
                 alt="Vercel logo"
                 className="my-0 mx-auto"
               />
             </Section>
             <Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0 leading-normal">
               Welcome to our test project with <strong>Resend!</strong>
             </Heading>
             <Text className="text-black text-[14px] ">Hello {username},</Text>
             <Text className="text-black text-[14px] ">
               We're happy to have you onboard!
             </Text>
             <Text className="text-black text-[14px] ">
               <strong>{invitedByUsername}</strong> has created this to show how
               we can send emails with Resend and react.email
             </Text>
              <Section className="text-center mt-[32px] mb-[32px]">
               <Button
               
                 className="bg-[#000000] rounded text-white text-[12px] p-7 font-semibold no-underline text-center"
                 href={inviteLink}
               >
                 Share on Twitter!
               </Button>
             </Section>
             <Text className="text-black text-[14px] ">
               or copy and paste this URL into your browser:{" "}
               <Link href={inviteLink} className="text-blue-600 no-underline">
                 {inviteLink}
               </Link>
             </Text>
             <Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" />
             <Text className="text-[#666666] text-[12px]">
               This invitation was intended for{" "}
               <span className="text-black">{email} </span>.This invite was sent
               by{" "}
               <span className="text-black">
                 (
                 <Link
                   href="https://twitter.com/iroro_chad"
                   className="text-blue-600 no-underline"
                 >
                   {invitedTwitterLink}
                 </Link>
                 )
               </span>{" "}
               If you were not expecting this invitation, you can ignore this
               email. If you are concerned about your account's safety, please
               reply to this email to get in touch with us.
             </Text>
           </Container>
         </Body>
       </Tailwind>
     </Html>
   );
 };
  export default WelcomeEmail;

Sending Email With Resend:


Finally, it’s time to send out our email. To do this, make sure you’ve installed Resend.

Now, go back to the HomePage.tsx file you created in the src/components folder, and let’s begin the magic!

You already have this:

const [formData, setFormData] = useState({ name: "", email: "" });


const handleFormSubmit = async (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
// we’d magic code here
}

Now, we’ll just update that part a little to actually make the magic happen.


Replace the above code with : 

const [formData, setFormData] = useState({ username: "", email: "" });
 const [formSuccess, setFormSuccess] = useState(false);


 const handleFormSubmit = async (e: React.MouseEvent<HTMLElement>) => {
   e.preventDefault();
   if (!formData.username || !formData.email) {
     alert("Name and Email are required fields.");
     return; // Prevent further execution
   }
   const res = await fetch(`/api/`, { //request to the http://localhost:3000/api/ server
     method: "POST",
     body: JSON.stringify({
       username: formData.username,
       email: formData.email,
     }),
     headers: {
       "Content-Type": "application/json",
     },
   });


   if (res.status === 200) {
     // Email sent successfully, clear the form & redirect to the thank you page.
     setFormSuccess(true);
     setFormData({ username: "", email: "" });
   } else {
     // Handle other cases (e.g., server errors) here.
     alert("We are having some error sending the email.");
   }
 };

Does that look easy to understand? It should. What is happening there is that we are simply saying if the user doesn’t have a name and email address, and they click on the submit button, alert them that all of the fields are required. But, if they entered their name and email, then try to send the data to our server using the built-in javascript fetch. If the response code is 200, then redirect them to another page ( The thank you page). Otherwise, simply alert us that we couldn’t send the email!

We’re not done yet. We are not actually redirecting the user per se, but we’re showing them a different screen component. This means we have to show a component depending on the state of the form and that’s why we have :

Simply replace the return statement with the code as follows.


return (
   <section className="bg-slate-900 h-screen">
     <main className=" text-gray-50 flex flex-col items-center justify-between  p-24">
       {formSuccess && <ThankYouPage username={formData.username} />}
       <div className="">
         <h1 className="text-6xl">Welcome</h1>
         <p className="pt-4">Please provide your details to continue.</p>
       </div>

    // rest of our componets in the palce. Please see the Homepage.tsx file code above.
     </main>
   </section>
 );
};

Alright, we’re done there. Now, let's head over to the API server.

Sending an email from the API folder :

Inside your app folder, create a new folder called api. Inside the newly created app folder, create a new file named route.ts  

In version 13, Next.js introduced a new App Router built on React Server Components, which supports shared layouts, nested routing, loading states, error handling, and more.

With that said, the pages file in the route.ts file will act as the root file in the api folder. Thus, we can make our API call to that file.

Inside that file, add the following code.

import { Resend } from "resend";
import {NextRequest, NextResponse } from "next/server";
import WelcomeEmail from "../components/welcomeEmail";


const resend = new Resend("re_123456apikeyhere"); // replace with your API key


interface APIType {
 username: string;
 email: string;
}


export async function POST(req: NextRequest) {
 const { username, email, } = await req.json();
 try {
 
   const data = await resend.emails.send({
     from: "Iroro Chadere <contact@yourdomain.com>", // use your custom domain name here
     to: `${email}`, // the email address you want to send a message
     subject: "Hello world Email Test",
     react: WelcomeEmail({ username, email }), // the email template design
   });


   return NextResponse.json(data);
 } catch (error) {
   return NextResponse.json({ error });
 }
}

Let’s talk about what’s happening there. We created a new API file, which we’d send our requests. The file accepts two parameters, the name and email of the user. Inside the async function, we use a try-catch to try to send the requests and catch errors if any. Inside the try block, we’re sending out the email to the user with the WelcomeEmail component that we imported.

Now we have our codes, save all the files, and simply spin up the server by running npm run dev or yarn dev

Once you do, and if everything goes well for you, you should see all our magic working well.

For some reason, my own server is taking some more seconds to process than usual. But anyway, it's working and you can try to speed yours up a little bit.

So, so far, our form is working, our user is getting the email and we can view the logs from resend logs to confirm that the user did receive the email! Looking sweet, right?!

Conclusion :

In this article, we've seen what Resend is, the purpose of Resend, and most importantly, how to use Resend + Next.js to send emails.
I hope you were able to find something valuable from this article. If you love this article, I'd want you to share it with your friends, and most importantly, don't forget to stick around for another article like this!