DevStacked
May 29, 202613 min read

How to Setup Resend Email in Next.js 16 (2026 Complete Beginner Guide)

Sending emails is one of the most common requirements in modern web applications.

Whether you're building:

  • A contact form
  • Authentication system
  • SaaS application
  • Newsletter platform
  • E-commerce store

You'll eventually need a reliable way to send emails.

In the past, developers often relied on SMTP providers and complicated email configurations. Today, services like Resend make email delivery significantly easier with a modern API-first approach.

In this guide, you'll learn how to integrate Resend with Next.js 16 using the App Router, create a contact form, send transactional emails, build reusable React Email templates, verify your domain, and deploy everything to production.

By the end of this tutorial you'll know how to:

✅ Create a Resend account
✅ Generate API keys
✅ Send emails using API Routes
✅ Send emails using Server Actions
✅ Create React Email templates
✅ Verify a custom domain
✅ Deploy to Vercel


What We'll Build

Here's the flow we'll create:

   User submits form
           
Server Action / API Route
           
      Resend API
           
      User Inbox

Resend Nextjs Email Form

When a visitor submits their email address, Next.js will securely send a request to Resend, which then delivers the email to the recipient.


What is Resend?

Resend is a modern transactional email platform built specifically for developers.

Unlike traditional SMTP providers, Resend offers a simple API that allows you to send emails with minimal configuration.

Some of its key features include:

  • Simple API integration
  • React Email support
  • Fast email delivery
  • Email analytics
  • Domain verification
  • Excellent developer experience
  • Great documentation

Common use cases include:

  • Contact forms
  • Welcome emails
  • Password reset emails
  • OTP verification emails
  • SaaS notifications
  • E-commerce receipts

Why Use Resend Instead of SMTP?

Traditional SMTP setups can become frustrating.

You often need to configure:

  • SMTP servers
  • Ports
  • Authentication
  • SSL/TLS settings
  • Email clients

Resend eliminates most of this complexity.

Instead of configuring SMTP manually, you simply send a request like this:

await resend.emails.send({
  from: "Acme <onboarding@resend.dev>",
  to: "user@example.com",
  subject: "Hello World",
  html: "<p>Hello from Resend</p>",
});

Resend vs SMTP

FeatureResendTraditional SMTP
Easy Setup
API-Based
React Email Support
AnalyticsLimited
Developer ExperienceExcellentAverage
Modern DocumentationVaries

Prerequisites

Before getting started, make sure you have:

  • Node.js installed
  • Basic React knowledge
  • Basic Next.js knowledge
  • VS Code or another editor

Recommended:

  • Custom domain
  • Vercel account

Create a Next.js 16 Project

Create a new Next.js application:

npx create-next-app@latest resend-email-guide

For this tutorial, choose:

  • TypeScript
  • Tailwind CSS
  • React Compiler
  • src directory

Move into the project:

cd resend-email-guide

Start the development server:

npm run dev

Why These Options?

  • TypeScript improves code quality and catches errors early.
  • Tailwind CSS speeds up UI development.
  • App Router is the recommended routing system in Next.js 16.
  • React Compiler automatically memoizes components and hooks to eliminate unnecessary re-renders

Install Resend

Install the official Resend SDK:

npm install resend

This package allows your application to communicate with the Resend API.


Create a Resend Account

Visit:

https://resend.com

Then:

  1. Create an account
  2. Verify your email address
  3. Open the dashboard

Generate a Resend API Key

Inside the Resend dashboard:

  1. Open API Keys
  2. Click Create API Key
  3. Copy the generated key

Create a .env.local file:

RESEND_API_KEY=your_api_key_here

Never expose your API key in client-side code. API keys should only be used on the server.


Create a Reusable Resend Client

Instead of creating a new Resend instance everywhere, create a reusable client.

Create:

src/lib/resend.ts
import { Resend } from "resend";

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

Now you can import this client throughout your application.


Create Your First Email API Route

Create:

src/app/api/send/route.ts

Add the following code:

import { isValidEmail } from "@/lib/helpers";
import { resend } from "@/lib/resend";

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

  if (!email) {
    return Response.json(
      { error: "Email is required" },
      { status: 400 }
    );
  }

  if (!isValidEmail(email)) {
    return Response.json(
      { error: "Please enter a valid email" },
      { status: 400 }
    );
  }

  try {
    const data = await resend.emails.send({
      from: "onboarding@resend.dev",
      to: email,
      subject: "Hello from Next.js 16",
      html: "<p>Email sent successfully!</p>",
    });

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

Understanding the Code

Creating the Email Request

await resend.emails.send(...)

This sends an email through the Resend API.

Returning Responses

Response.json(...)

Returns a JSON response back to the frontend.

Validation

Before sending emails, we validate user input to prevent unnecessary API calls.


Create an Email Validation Helper

Create:

src/lib/helpers.ts
export const isValidEmail = (
  email: string
) =>
  /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(
    email
  );

Why Validate Emails?

Validation helps:

  • Improve user experience
  • Reduce API usage
  • Prevent invalid submissions
  • Avoid unnecessary errors

Why Emails Should Be Sent Server-Side

Many beginners try sending emails directly from the frontend.

This is dangerous because:

  • API keys become public
  • Attackers can abuse your account
  • Security risks increase

Always send emails using:

  • Route Handlers
  • Server Actions
  • Backend APIs

Never expose API keys in client-side code.


Build a Contact Form

Create:

src/app/page.tsx
"use client";

import { useActionState } from "react";
import { isValidEmail } from "@/lib/helpers";

async function handleSubmit(
  _: unknown,
  formData: FormData
) {
  const email = formData.get("email") as string;

  if (!email) {
    return {
      message: "Email is required",
      success: false,
    };
  }

  if (!isValidEmail(email)) {
    return {
      message: "Please enter a valid email",
      success: false,
      email,
    };
  }

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

  if (response.ok) {
    return {
      message: "Email sent!",
      success: true,
    };
  }

  return {
    message: "Something went wrong",
    success: false,
    email,
  };
}

export default function HomePage() {
  const [state, action, isPending] = useActionState(handleSubmit, { message: '', success: false, email: '' });

  return (
    <main className="min-h-screen flex flex-col items-center justify-center bg-gray-100 p-4">
      <h1 className="text-2xl font-bold mb-4">Subscribe to our Newsletter</h1>
      <form action={action}>
        <input defaultValue={state.email} type="email" name="email" placeholder="Enter your email" className="mb-4 p-2 border rounded w-full" required />
        <button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded w-full cursor-pointer" disabled={isPending}>
          {isPending ? "Sending..." : "Subscribe"}
        </button>
      </form>
      {state.message &&
        <p className={`mt-4 ${state.success ? 'text-green-500' : 'text-red-500'}`}>{state.message}</p>
      }
    </main>
  );
}

Understanding useActionState

useActionState() helps manage form state automatically.

It provides:

  • Current state
  • Form action
  • Loading state

Without it, you'd need multiple state variables and manual loading logic.


Test the Contact Form

Run the application:

npm run dev

Submit an email address.

Expected flow:

  1. User enters email
  2. Email is validated
  3. API Route executes
  4. Resend sends email
  5. User sees success message
  6. Email arrives in inbox

Using Server Actions Instead of API Routes

Next.js 16 encourages using Server Actions for form submissions.

Server Actions reduce boilerplate and keep logic closer to components.

API Routes vs Server Actions

API RoutesServer Actions
Separate endpointBuilt into components
More boilerplateLess boilerplate
Traditional approachModern Next.js
Great for APIsGreat for forms

Create a Server Action

Create:

src/actions/send-email.ts
"use server";

import { resend } from "@/lib/resend";
import { isValidEmail } from "@/lib/helpers";

export async function sendEmail(
  _: unknown,
  formData: FormData
) {
  const email = formData.get("email") as string;

  if (!email) {
    return {
      message: "Email is required",
      success: false,
    };
  }

  if (!isValidEmail(email)) {
    return {
      message: "Please enter a valid email",
      success: false,
      email,
    };
  }

  try {
    await resend.emails.send({
      from: "onboarding@resend.dev",
      to: email,
      subject: "Hello from Next.js 16",
      html: "<p>Email sent successfully!</p>",
    });

    return {
      message: "Email sent!",
      success: true,
    };
  } catch {
    return {
      message: "Something went wrong",
      success: false,
      email,
    };
  }
}

Now update /src/app/page.tsx

const [state, action, isPending] = useActionState(handleSubmit, { message: '', success: false, email: '' });

to

const [state, action, isPending] = useActionState(sendEmail, { message: '', success: false, email: '' });

Now your form can call the Server Action directly without using a separate API route.


Send Beautiful Emails with React Email

While plain HTML works, React Email makes creating templates much easier.

Install the packages:

npm install react-email @react-email/components

Benefits:

  • Reusable templates
  • Type safety
  • Responsive layouts
  • Better maintainability

Create Your First Email Template

Create:

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

interface WelcomeEmailProps {
  username: string;
}

export default function WelcomeEmail({
  username,
}: WelcomeEmailProps) {
  return (
    <Html>
      <Body>
        <Container>
          <Heading>
            Welcome!
          </Heading>

          <Text>
            Hello {username}, thanks for joining our
            platform.
          </Text>

          <Button href="https://example.com">
            Get Started
          </Button>
        </Container>
      </Body>
    </Html>
  );
}

Send Dynamic Emails

Instead of hardcoding HTML:

html: "<p>Hello</p>";

Use React Email templates:

import WelcomeEmail from "@/components/emails/welcome";

await resend.emails.send({
  from: "onboarding@resend.dev",
  to: "user@example.com",
  subject: "Welcome!",
  react: WelcomeEmail({
    username: "Muhammad",
  }),
});

This makes your emails reusable and easier to maintain.


Verify Your Domain (Very Important)

For production applications, domain verification is essential.

Instead of:

onboarding@resend.dev

You'll eventually send emails from:

hello@yourdomain.com

Why Domain Verification Matters

Verified domains provide:

  • Better deliverability
  • Better branding
  • Higher inbox placement
  • Reduced spam risk

Add a Domain in Resend

Inside the Resend dashboard:

  1. Open Domains
  2. Click Add Domain
  3. Enter your domain
  4. Copy the DNS records

Configure DNS Records

Resend typically provides:

  • SPF
  • DKIM
  • DMARC

These records help email providers trust your emails.

SPF

Defines which servers can send emails for your domain.

Example:

v=spf1 include:_spf.resend.com ~all

DKIM

Adds a cryptographic signature proving emails are legitimate.

DMARC

Defines how providers should handle suspicious emails.

Example:

v=DMARC1; p=none;

Testing Emails Locally

When testing locally:

  • Use test email addresses
  • Monitor API limits
  • Verify responses
  • Check inbox and spam folders

Free plans may have sending restrictions.


Common Errors and Fixes

Invalid API Key

Check:

RESEND_API_KEY=

Make sure the value is correct.

Restart the development server after changes.


Domain Not Verified

Symptoms:

  • Emails fail
  • Emails land in spam
  • Delivery issues

Solution:

  • Verify DNS records
  • Wait for propagation
  • Re-check configuration

Rate Limit Errors

Free plans have sending limits.

Avoid:

  • Infinite loops
  • Automated testing spam
  • Excessive test emails

Proper Error Handling

Always wrap email requests in try/catch.

try {
  await resend.emails.send();
} catch (error) {
  console.error(error);
}

Good error handling makes debugging much easier.


Email Deliverability Best Practices

To avoid spam folders:

  • Use verified domains
  • Avoid ALL CAPS subject lines
  • Keep HTML clean
  • Use proper sender names
  • Include text alternatives
  • Avoid excessive links

Deploy to Vercel

Build your application:

npm run build

Push your code to GitHub and import the repository into Vercel.


Add Environment Variables in Vercel

Inside your Vercel dashboard:

  1. Open Project Settings
  2. Navigate to Environment Variables
  3. Add:
RESEND_API_KEY

Redeploy your project after adding environment variables.


Real-World Use Cases

Use CaseExample
Contact FormsPortfolio Websites
OTP EmailsAuthentication Systems
Welcome EmailsSaaS Products
Password ResetUser Accounts
Order ReceiptsE-commerce Stores
NotificationsDashboards
NewslettersContent Platforms

Common Beginner Mistakes

Sending Emails From the Client

Never expose API keys publicly.
Always use server-side code.

Hardcoding API Keys

Use environment variables instead.

Skipping Validation

Always validate user input before sending emails.

Forgetting Domain Verification

This can significantly hurt email deliverability.


Frequently Asked Questions

Is Resend Free?

Yes. Resend offers a free tier suitable for development and small projects.

Can I Use Resend with Next.js Server Actions?

Absolutely. Server Actions are one of the best ways to integrate Resend with Next.js 16.

Do I Need a Custom Domain?

Not for testing. However, production applications should verify a custom domain.

Can I Send HTML Emails?

Yes. You can send raw HTML or use React Email templates.

Does Resend Work with Vercel?

Yes. Resend integrates perfectly with Vercel deployments.


What's Next?

After learning the basics, explore:

  • Scheduled emails
  • Email queues
  • Background jobs
  • Batch email sending
  • Attachments
  • Analytics
  • Webhooks

Conclusion

Resend is one of the easiest ways to send transactional emails in Next.js 16.

Compared to traditional SMTP providers, it offers a significantly better developer experience, simpler setup, and excellent React Email integration.

In this guide, you learned how to:

  • Setup Resend
  • Generate API keys
  • Send emails using API Routes
  • Send emails using Server Actions
  • Create React Email templates
  • Verify domains
  • Deploy to Vercel

From here, you can build:

  • Authentication systems
  • SaaS products
  • Newsletter platforms
  • E-commerce workflows

Happy coding 🚀

Helpful Resources

Continue Learning

Source Code: https://github.com/Muhammad-Ali-sma/Nextjs16_Resend_Email_Setup

ResendNext.js 16EmailReact EmailServer ActionsContact FormTransactional EmailsVercel
Share On