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.

Email Functionality

Introduction

Payload comes ready to send your application's email. Whether you simply need built-in password reset email to work or you want customers to get an order confirmation email, you're almost there. Payload makes use of NodeMailer for email and won't get in your way for those already familiar.

For email to send from your Payload server, some configuration is required. The settings you provide will be set in the email property object of your payload init call. Payload will make use of the transport that you have configured for it for things like reset password or verifying new user accounts and email send methods are available to you as well on your payload instance.

Configuration

Three ways to set it up

  1. Default: When email is not needed, a mock email handler will be created and used when nothing is provided. This is ideal for development environments and can be changed later when ready to go to production.
  2. Recommended: Set the transportOptions and Payload will do the set up for you.
  3. Advanced: The transport object can be assigned a nodemailer transport object set up in your server scripts and given for Payload to use.

The following options are configurable in the email property object as part of the options object when calling payload.init().

OptionDescription
fromName *The name part of the From field that will be seen on the delivered email
fromAddress *The email address part of the From field that will be used when delivering email
transportThe NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set
transportOptionsAn object that configures the transporter that Payload will create. For all the available options see the NodeMailer documentation or see the examples below
logMockCredentialsIf set to true and no transport/transportOptions, ethereal credentials will be logged to console on startup

* An asterisk denotes that a property is required.

Use SMTP

Simple Mail Transfer Protocol (SMTP) options can be passed in using the transportOptions object on the email options. See the NodeMailer SMTP documentation for more information, including details on when secure should and should not be set to true.

Example email options using SMTP:

1
payload.init({
2
email: {
3
transportOptions: {
4
host: process.env.SMTP_HOST,
5
auth: {
6
user: process.env.SMTP_USER,
7
pass: process.env.SMTP_PASS,
8
},
9
port: Number(process.env.SMTP_PORT),
10
secure: Number(process.env.SMTP_PORT) === 465, // true for port 465, false (the default) for 587 and others
11
requireTLS: true,
12
},
13
fromName: 'hello',
14
fromAddress: 'hello@example.com',
15
},
16
// ...
17
})

Use an email service

Many third party mail providers are available and offer benefits beyond basic SMTP. As an example, your payload init could look like this if you wanted to use SendGrid.com, though the same approach would work for any other NodeMailer transports shown here or provided by another third party.

1
import payload from 'payload'
2
import nodemailerSendgrid from 'nodemailer-sendgrid'
3
4
const sendGridAPIKey = process.env.SENDGRID_API_KEY
5
6
payload.init({
7
...(sendGridAPIKey
8
? {
9
email: {
10
transportOptions: nodemailerSendgrid({
11
apiKey: sendGridAPIKey,
12
}),
13
fromName: 'Admin',
14
fromAddress: 'admin@example.com',
15
},
16
}
17
: {}),
18
})

Use a custom NodeMailer transport

To take full control of the mail transport you may wish to use nodemailer.createTransport() on your server and provide it to Payload init.

1
import payload from 'payload'
2
import nodemailer from 'nodemailer'
3
4
const payload = require('payload')
5
const nodemailer = require('nodemailer')
6
7
const transport = await nodemailer.createTransport({
8
host: process.env.SMTP_HOST,
9
port: 587,
10
auth: {
11
user: process.env.SMTP_USER,
12
pass: process.env.SMTP_PASS,
13
},
14
})
15
16
payload.init({
17
email: {
18
fromName: 'Admin',
19
fromAddress: 'admin@example.com',
20
transport,
21
},
22
// ...
23
})

Sending Mail

With a working transport you can call it anywhere you have access to payload by calling payload.sendEmail(message). The message will contain the to, subject and email or text for the email being sent. To see all available message configuration options see NodeMailer.

Mock transport

By default, Payload uses a mock implementation that only sends mail to the ethereal capture service that will never reach a user's inbox. While in development you may wish to make use of the captured messages which is why the payload output during server output helpfully logs this out on the server console.

To see ethereal credentials, add logMockCredentials: true to the email options. This will cause them to be logged to console on startup.

1
payload.init({
2
email: {
3
fromName: 'Admin',
4
fromAddress: 'admin@example.com',
5
logMockCredentials: true, // Optional
6
},
7
// ...
8
})

Console output when starting payload with a mock email instance and logMockCredentials: true

1
[06:37:21] INFO (payload): Starting Payload...
2
[06:37:22] INFO (payload): Payload Demo Initialized
3
[06:37:22] INFO (payload): listening on 3000...
4
[06:37:22] INFO (payload): Connected to MongoDB server successfully!
5
[06:37:23] INFO (payload): E-mail configured with mock configuration
6
[06:37:23] INFO (payload): Log into mock email provider at https://ethereal.email
7
[06:37:23] INFO (payload): Mock email account username: hhav5jw7doo4euev@ethereal.email
8
[06:37:23] INFO (payload): Mock email account password: VNdGcvDZeyEhtuPBqf

The mock email handler is used when payload is started with neither transport or transportOptions to know how to deliver email.

Using multiple mail providers

Payload supports the use of a single transporter of email, but there is nothing stopping you from having more. Consider a use case where sending bulk email is handled differently than transactional email and could be done using a hook.

Next

TypeScript - Overview