Skip to content

Sending Email

Sending emails is something almost every web app needs - for things like welcoming new users, resetting passwords, or sending notifications. In this guide, we will learn how to send emails in a Next.js app using two tools: react-email and Resend.

  • react-email - lets you build email templates using React components (just like building a normal web page)
  • Resend - is the service that actually sends the email for you
  1. Install the required packages: Run these commands in your terminal to install everything you need:

    Terminal window
    npm install @react-email/ui -D -E
    npm install react-email react react-dom -E
  2. Add a script to package.json: Open your package.json file and add this script. This gives you a easy command to preview your emails while building them:

    "scripts": {
    "email:dev": "react-email dev -p 3001",
    }
  3. Create an email template: Create a new file called WelcomeEmail.tsx inside an emails/ folder. This file defines what your email will look like:

    // emails/WelcomeEmail.tsx
    import { Html, Head, Body, Link, Container } from "react-email";
    import * as React from "react";
    export const WelcomeEmail = ({name}: {name: string}) => {
    return (
    <Html>
    <Head>
    <title>My email title</title>
    </Head>
    <Preview>Email preview text</Preview>
    <Body>
    <Container>
    <p>
    Thank you for signing up, {name}! We're excited to have you on board!
    </p>
    <Link href="https://example.com" >example.com</Link>
    </Container>
    </Body>
    </Html>
    );
    };
  4. Update your .gitignore: Add the following line to your .gitignore file. This tells Git to ignore the auto-generated .react-email/ folder so it does not get pushed to your repo:

    .react-email/
  5. Preview your emails locally: Run this command to start a local preview server on port 3001 where you can see what your emails look like:

    Terminal window
    npm run email:dev
  6. Set up Resend: Go to resend.com, create an account, and get your API key. Then add it to your .env.local file like this:

    RESEND_API_KEY=your_resend_api_key_here

    Configure your domain: By default, Resend lets you send emails only from their test address. To send emails from your own domain (like no-reply@example.com), you need to verify your domain with Resend first. Here is how:

    • Go to your Resend dashboard and click Domains -> Add Domain
    • Enter your domain name, for example example.com
    • Resend will give you a few DNS records (like TXT and MX records) to add to your domain settings
    • Go to wherever you manage your domain (like Namecheap, Cloudflare, GoDaddy, etc.) and add those DNS records
    • Come back to Resend and click Verify - once verified, your domain is ready to use

    After verifying, you can send emails from any address on that domain, for example no-reply@example.com or hello@example.com.

  7. Write the function to send emails: In Next.js, you do not create a special API route just for sending emails. Instead, you write a helper function and call it wherever you need it - for example, right after a user signs up.

    First, install the Resend package:

    Terminal window
    npm install resend

    Then create the helper function:

    // lib/sendEmail.ts
    import { Resend } from "resend";
    import { WelcomeEmail } from "@/emails/WelcomeEmail";
    const resend = new Resend(process.env.RESEND_API_KEY);
    export async function sendEmail(to: string, name: string) {
    const { data, error } = await resend.emails.send({
    from: "no-reply@example.com", // must be from your verified domain
    to: to,
    subject: "Welcome to our app!",
    react: WelcomeEmail({ name }),
    });
    if (error) {
    console.error("Failed to send email:", error);
    return { success: false, error };
    }
    return { success: true, data };
    }

    Now you can call sendEmail() from anywhere in your app. For example, after a user signs up:

    // app/api/register/route.ts (or anywhere you handle sign up)
    import { sendEmail } from "@/lib/sendEmail";
    // ... after saving the user to the database:
    await sendEmail(user.email, user.name);

    Make sure the from address uses your verified domain (for example no-reply@example.com). If your domain is not verified yet, go back to step 6 and complete the domain setup first.

There are two main ways to style your emails: using inline styles (a style object) or using Tailwind CSS.

You can add styles directly to your email components using a style object. This is a safe approach because it works consistently across different email clients (like Gmail, Outlook, etc.):

// emails/WelcomeEmail.tsx
import { Html, Head, Body, Link, Container } from "react-email";
import * as React from "react";
const styles: React.CSSProperties = {
container: {
padding: '20px',
backgroundColor: '#f9f9f9',
borderRadius: '8px',
},
link: {
color: '#1a73e8',
textDecoration: 'none',
},
};
export const WelcomeEmail = ({name}: {name: string}) => {
return (
<Html>
<Head>
<title>My email title</title>
</Head>
<Preview>Email preview text</Preview>
<Body>
<Container style={styles.container}>
<p>
Thank you for signing up, {name}! We're excited to have you on board!
</p>
<Link href="https://example.com" style={styles.link}>example.com</Link>
</Container>
</Body>
</Html>
);
};

You can also write the styles directly inside the JSX instead of putting them in a separate object - both ways work fine:

export const WelcomeEmail = ({name}: {name: string}) => {
return (
<Html>
<Head>
<title>My email title</title>
</Head>
<Preview>Email preview text</Preview>
<Body>
<Container style={{backgroundColor: '#f9f9f9', padding: '20px', borderRadius: '8px'}}>
<p>
Thank you for signing up, {name}! We're excited to have you on board!
</p>
<Link href="https://example.com" style={{color: '#1a73e8', textDecoration: 'none'}}>example.com</Link>
</Container>
</Body>
</Html>
);
};

If you prefer Tailwind CSS, react-email has built-in support for it. Just wrap your email content inside a <Tailwind> component and use Tailwind classes as normal:

// emails/WelcomeEmail.tsx
import { Html, Head, Body, Link, Container, Tailwind } from "react-email";
import * as React from "react";
export const WelcomeEmail = ({name}: {name: string}) => {
return (
<Html>
<Head>
<title>My email title</title>
</Head>
<Preview>Email preview text</Preview>
<Tailwind>
<Body>
<Container className="bg-gray-100 p-5 rounded-lg">
<p className="text-gray-800">
Thank you for signing up, {name}! We're excited to have you on board!
</p>
<Link href="https://example.com" className="text-blue-600 hover:underline">example.com</Link>
</Container>
</Body>
</Tailwind>
</Html>
);
};