Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.
AuthorNick Vogel

How to set up Nodemailer and Resend email adapters in Payload

Community Guide
AuthorNick Vogel

In this guide we’re going to use the Payload email adapter to allow our application to send emails, focusing on two main options: SendGrid with Nodemailer, and Resend.

At the time of this recording, these are the two official email adapters that Payload supports.

The Nodemailer adapter is certainly the easiest migration path if you already had email set up in a previous project. This allows you to use any Nodemailer-transport like SMTP, Resend, and SendGrid.

Most email providers should be available using this option.

The second option is Resend, which uses the Resend REST API to send emails. This is lightweight compared to Nodemailer and may be preferred if you’re using a serverless platform like Vercel.

We’ll cover each of these in detail.

Both adapters need to be imported from their respective packages into your Payload config as follows:

1
import {nodemailerAdapter} from ‘@payloadcms/email-nodemailer’
2
import {resendAdapter} from ‘@payloadcms/email-resend’

It should be noted that both of these packages do need to be installed via your console before we can get started as follows:
npm install @payloadcms/plugin-email-nodemailer @payloadcms/email-resend

And while you could use multiple email adapters for different use cases, we’ll focus on just getting each of these up and running separately as single options.

Configuring Nodemailer

Since we're going to focus first on Nodemailer, be sure you comment out Resend first in your config.

Once imported, you will need to add the email option to your Payload config if you haven’t already.

1
email: nodemailerAdapter({ // Assigned nodemailerAdapter
2
defaultFromAddress: 'info@midlowebdesign.com', //
3
defaultFromName: 'Nick',
4
transportOptions { // This is where we'll provide SendGrid information (next step)
5
host: ,
6
port: ,
7
auth: {
8
user: ,
9
pass: ,
10
}
11
}
12
})

Now, let’s set up a SendGrid account and get this working.

Signing Up for SendGrid

First, you’ll go to sendgrid.com and click “Start for free.”

Once you’re signed in and verified, you’ll see a dashboard with some next steps.

You should follow the instructions on how to get your mail exchange servers set up in your DNS, which will prevent your emails from ending up in spam.

Getting Your SendGrid API Key

On the left side, you can select “Email API,” then "Integration Guide.” Once there, you’ll have two options, “Web API” or “SMTP Relay.” Choose SMTP Relay, and you’ll see a screen that asks you to create an API key. Name it and click “Create Key.” This will show you an API key that you’ll want to copy and paste right away into your .env file under the SMTP_PASS environment variable (example below).

Setting Up Sender Identity So You Can Send Emails

Next, you will be able to gather the “host,” “port,” and “user” options you need. Optionally include these all as SMTP_HOST, SMTP_PORT, and SMTP_USER in your .env file and assign them to your host, port, and user options.

In our case, we’re going to use port 465, which is for secure connections.

1
DOMAIN_NAME=https://example.com
2
SMTP_PASS=password-goes-here
3
SMTP_HOST=smti.sendgrid.net
4
SITP_PORT=465
5
SMTP_USER=apikey|

You can then check that you’ve updated your settings and verify your integration if you’d like. Either way, you’ll want to test this functionality by using the “Forgot password” link on your Payload login page.

Now that you have your SendGrid environment variables in place, you can copy them over to your Payload config.

1
email: nodemailerAdapter({
2
defaultFromAddress: 'info@midlowebdesign.com',
3
defaultFromName: 'Nick',
4
transportOptions {
5
host: process. env.SMTP_HOST,
6
port: process. env.SMTP_PORT,
7
auth: {
8
user: process. env.SMTP_USER,
9
pass: process. env.SMTP_PASSWORD,
10
}
11
}
12
})

In order to test this, you still need to set up your sender identity within SendGrid. This is done easily by clicking 'Create sender identity' and fill out the fields therein. Again, this is for spam laws, so it is required.

Once that is done, you'll be able to verify your sender within SendGrid.

Finally, spin up your server again, click 'Forgot password?', enter the email address you'd like to test (make sure it's an existing user on your project), and verify the email has been sent.

Configuring Resend

Your other email option is the Resend configuration.

You’ll set this up much the same way as you did your Nodemailer adapter. We’ll comment out the Nodemailer adapter information and add a new email option with resendAdapter() assigned to it.

Then, open an empty object and we can get started.

1
email: resendAdapter({
2
defaultFromAddress: 'info@midlowebdesign.com',
3
defaultFromName: 'Nick',
4
apiKey: process. env.RESEND_API,
5
}
6
})

Setting Up the Resend Email Adapter

First, go to resend.com and click “Get Started.” Create a new Resend account if you don’t already have one. Once confirmed and logged in, you should be brought to an onboarding page. If not, go to resend.com/onboarding.

Getting Your Resend API Key

Add an API Key, and copy this and paste it as the environment variable RESEND_API. Assign this environment variable to the apiKey option for your resendAdapter, and you’re good to go.

Once you have that in place, you can return to the Resend onboarding page and click "Send email" to move through the onboarding process.

Verifying Your Sending Domain

Next, you're going to want to add a domain in Resend. So we'll add our domain and hit add.

And now you're going to need to add these DNS records to your DNS provider—and each DNS provider is going to be different. Once you are done, you can click verify DNS records within Resend—this should only take a few seconds.

You can now test your Resend integration by restarting your server and following the forgot password flow at your Payload login screen. Upon restarting your server, return to the login page, and click Forgot Password—we should receive an email asking to reset our password!

Sending emails from hooks in Payload

Once your email adapter is configured (either with Nodemailer or Resend), you can use req.payload.sendEmail() inside any hook to send emails based on changes in your collections or globals.

Here’s an example of how to send an email when a document in the posts collection changes:

1
hooks: {
2
afterChange: [
3
async ({ req: { payload }, collection }) => {
4
await payload.sendEmail({
5
to: 'nick@midlowebdesign.com',
6
subject: `Change made in ${collection.slug}`,
7
text: `Change made in ${collection.slug}`,
8
});
9
},
10
],
11
},

And now an email will be sent any time a change is made to this collection.

The power of Payload email adapters

These email adapters are just another example of how flexible and powerful Payload really is.

You can do more than just send error messages and forgot password requests via email. You can also use this to notify teams or users that changes have been made in different globals or collections, or if you have an important collection, you can send emails whenever an item in a collection has been deleted.