omniux logo
Payload & React Email

Payload & React Email: Creating dynamic emails for everyone


Written by Mark Barton

19th of August, 2023


React Email is a brand new email library from the Resend team. It allows us to create powerful dynamic emails with complex layouts, providing value to our users and simplifying the development process. When paired with PayloadCMS, React Email can complement your booking system, subscription list, or even CMS user sign-up flow.

What is PayloadCMS?

For the uninitiated, PayloadCMS is a developer-friendly headless content management system with a heavy focus on rapid development and extendibility. Payload comes with a ton of built-in components, functions, and hooks that let us create full-featured websites, e-commerce platforms, and booking portals. It can even be used to help make games. Nodemailer is the default email provider, with support for Ethereal Mail out of the box to help you test in a safe, free environment.

What is React Email

React Email is an Email-first component library that lets you build your Emails with React and Tailwindcss, before rendering the resulting HTML into a email-friendly format. If you have worked with email design tools before, you'll know how much of a headache it can be to develop well-formatted and stylish emails, all while traversing a mountain of inline css. Fortunately, React Email does all the hard work for us.


Before we begin, this article won't show you how to set up an email provider. If you would like to learn how to do that, we recommend reading this article by Payload. If you are using Resend, This comment on the Payload Discord provides a full code sample of a custom transport using Resend.

React Email splits its library into individually installable components, as such, you will need to install each component as required. For this, we will install the HTML and Text component and the Render function. Enter the following code into your terminal;

Yarn installation code

yarn add react-email @react-email/html @react-email/text @react-email/render -E

Once your packages have been installed, add a folder called templates at the same level as your Payload.config.ts file. Next, create a file called NewUserEmail.tsx and enter the following code;

NewUserEmail.tsx code

import { Html } from '@react-email/html'

import { Text } from '@react-email/text'

import { render } from '@react-email/render'

type Props = {

name: string;


const Template: FC<Props> = ({ name }) => {

return (


<Text>Hello, {name}</Text>




export function newUserEmail(data: Props) {

return render(<Template{} />);


You have just created your first email! Notice that we first create the HTML for our email in the Template component. Then we pass it into the render() function, which converts our React code into email-friendly HTML. We can also pass props to our component, letting us dynamically populate our email. Now it's time to use it...

Sending your first email

We're going to test our email using Ethereal mail. Don't worry, Payload handles most of this for you! We just want to make sure we can access the temporary email address all mail is routed to. Inside your server.ts file, find your payload.init() function and add the following code;

Log Ethereal Mail credentials to the console

payload.init({ email: { fromName: "Admin", fromAddress: "", logMockCredentials: true }

// ...


Now your console will display your login details when you start up your app. Be aware, every time your app starts up or refreshes (due to code changes) your credentials will be reset and you will need to log back into your EtherealMail client. The message will look like this;

Resulting console log

[06:37:21] INFO (payload): Starting Payload...

[06:37:22] INFO (payload): Payload Demo Initialized

[06:37:22] INFO (payload): listening on 3000...

[06:37:22] INFO (payload): Connected to MongoDB server successfully!

[06:37:23] INFO (payload): E-mail configured with mock configuration

[06:37:23] INFO (payload): Log into mock email provider at

[06:37:23] INFO (payload): Mock email account username:

[06:37:23] INFO (payload): Mock email account password: VNdGcvDZeyEhtuPBqf

With your transport set up, let's create a scenario where we need to send an email. By default, your Payload code will have a collection called Users. We're going to send an email every time a user is added to Payload. We'll make use of the afterChange hook. This hook fires whenever changes to the collection are saved, for instance, creating a new user. Open your Users.ts file in the collections folder and add the following code;

afterChange hook at the collection level

hooks: {

afterChange: [sendNewUserEmail]


At this time, it might be a good idea to add a folder called hooks in your Payload project. Inside of this hooks folder, you can create a new file called sendNewUserEmail.ts. Inside this file, we're going to add an if condition that checks to see if the operation was 'create'. If true, we'll send a new email to the user.

Custom hook code

export const sendNewUserEmail = async ({ res: { payload }, doc, operation }) => {

if (operation === 'create') {

await payload.sendEmail({


from: 'Admin',

subject: 'New user added!'

html: newUserEmail({ name: doc.firstName + ' ' + doc.lastName })



That's it! Spin up your Payload instance, create a new user, and then log in to your EtherealMail account with the mock credentials provided in the console. You should see your newly formatted email! Obviously, it looks a bit boring, but with React Email you can style your component any way you like!

Build Your Business

Get started with our custom package builder;

What's included?

Access to marketing, development, & finance experts

Performance & marketing audits

Ad buying oppertunities through The US Open, Comcast, Apple, and more...

Not sure what services you want? Try our...

Service Quiz