PayloadCMS Email Adapters: Sending Emails Using SendGrid and Resend
Learn how to configure the email adapters in Payload CMS.
In this guide we’re going to use the Payload CMS email adapter to allow our application to send emails.
Learn how to configure the email adapters in Payload CMS.
In this guide we’re going to use the Payload CMS email adapter to allow our application to send emails.
At the time of this guide, you have two official email adapters that Payload CMS supports: Nodemailer and Resend. The Nodemailer adapter is what was provided by default in Payload version 2 and is still supported. It’s 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 the nodemailer adapter 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. You can import {nodemailerAdapter} from '@payload/email-nodemailer' and you can import {resendAdapter} from '@payloadcms/email-resend'. 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.
First up is the Nodemailer Configuration. Once imported, you will need to add the email option to your payload config if you haven’t already. Once you do that, you’ll assign the nodemailerAdapter() to the option, and open an empty object. You have the opportunity to define your defaultFromAddress and defaultFromName here. After you set those, you’ll need to add the transport option and assign nodemailer.createTransport() to it. You’ll then, again, open an empty object, which will contain your SendGrid information. You’ll need a host, port, and auth object with a user and pass option. You’ll want your host, user, and pass to all be environment variables.
So, let’s set up a SendGrid account and get this working.
First, you’ll go to sendgrid.com and, in the menu, click “Start for free.” You can sign up using your personal information, or use “sign up with Google” to sign up for a new account. We’ll sign up with Google. You’ll be asked to verify your email address and then a phone number. These are required because anti-spam laws are very strict and they need to be sure that you are a real person with ways to actually reach you.
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.
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.
Step 2 gives you 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.
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 login page.
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 our email option with Nodemailer adapter in it and add a new email option with resendAdapter() assigned to it. Then, open an empty object and we can get started. You’ll want to provide a defaultFromAddress and defaultFromName here, and then you’ll just need to provide an apiKey from Resend. Let’s set that up now.
First, go to Resend.com and click “Get Started.” Create a new Resend account if you don’t already have one. You can use GitHub, Google, or your email address. We’ll use our email address. You’ll then need to confirm your email address using the email Resend sends you. Once confirmed and logged in, you should be brought to an onboarding page. If not, go to resend.com/onboarding.
Add an API Key, and copy this and paste it as an environment variable, RESEND_API_KEY. Assign this environment variable to the apiKey option for your resendAdapter, and you’re good to go. You can test this out now by restarting your server and following the forgot password flow at your login screen.
You can send emails using either email adapter by using payload.sendEmail(). As I mentioned in my guides about hooks, you can use hooks to send an email during specific operations, so if there is an error in the application, we can add a root hook by adding a hook option to our payload config, open an empty object, set our afterError hook to be an empty array, then create an async anonymous function with req: {payload} and error as our arguments. We can then set a constand called errorEmail, set it equal to await payload.sendEmail() and open an empty object. You’ll need to include a couple of options here: to, subject, and html or text for the email being sent. There are more options, but support varies depending on the email adapter you’re using. Depending on your IDE and which hook you’re including sendEmail, you should see hints show up for which options are available to you.
“To” should be set to the email address you’d like to send the email to. This can be programmatically defined using data from your collection, global, or fields. Or, in our case, to a developer on our team that an error has occurred.
The “subject” option is the subject line of the email. You can use the error argument to send an email with the subject line that an error or {error.name} occurred.
Lastly, you’ll want to use text or html to send what the actual message is. You can use html if you want to style your email message before sending, or you can just include the message in plain text. Since this is an internal error message, let’s just use plain text. We’ll set the text option to include the message from the error. You don’t need to set a return value here, this will work just like this.
These email adapters are just another example of how flexible and powerful PayloadCMS 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.