Prerequisites
To send emails with Postmark, you must first sign up for an account; the free developer plan will work just fine.
Mailing is free and open-source, so there are no prerequisites.
Add Postmark
First, create a new server in Postmark and get the API token by going to Servers → Your server → API Tokens. You will need this token to be able to send emails.
Install the Postmark package:
yarn add postmark
Next, add the following environment variables to your .env
file:
POSTMARK_API_TOKEN=your-api-token
SMTP_HOST=smtp.postmarkapp.com
SMTP_PORT=587
SMTP_USERNAME=your-api-token
SMTP_PASSWORD=your-api-token
SMTP_FROM=Your Name <no_reply@your-domain.com>
Add Nodemailer (Optional)
You can use any email-sending package, but I'll be using Nodemailer in this guide. If you don't have it installed, you can add it to your project by running the following command:
yarn add nodemailer
Add Mailing
Install the following packages:
yarn add mailing-core next react react-dom
yarn add --dev mailing
Let's set up Mailing. Run the following command:
npx mailing
or npx mailing --typescript
if you are using TypeScript.
You should now have an emails
folder in your project root and the Mailing dev server should be running, so that you can live-preview your emails in the browser.
Let's configure the SMTP transport aka instruct Mailing to use Postmark to send emails. Open emails/index.ts
and replace it with the following:
import nodemailer from 'nodemailer'
import { buildSendMail } from 'mailing-core'
const sendMail = buildSendMail({
transport: nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT,
auth: {
user: process.env.POSTMARK_API_TOKEN,
pass: process.env.POSTMARK_API_TOKEN,
},
}),
defaultFrom: process.env.SMTP_FROM,
configPath: './mailing.config.json',
})
export default sendMail
Tada! You can now send emails using the sendMail
function. Let's create a simple magic link email template to test it out with Auth.js.
Create the magic link email template
Mailing uses MJML, which is great since MJML takes the pain away from building responsive emails.
Create a new file VerifyEmail.tsx
in emails/
and add the following code:
import React, { ReactElement } from 'react'
import { MjmlSection, MjmlColumn } from 'mjml-react'
import { Template } from 'mailing-core'
import Button from './components/Button'
import Text from './components/Text'
import BaseLayout from './components/BaseLayout'
import { spacing } from './theme'
type VerifyEmailProps = {
url: string
}
const VerifyEmail: Template<VerifyEmailProps> = ({ url }) => {
return (
<BaseLayout width={352}>
<MjmlSection cssClass='gutter'>
<MjmlColumn>
<Text paddingTop={spacing.s5} paddingBottom={spacing.s5}>
Click the button below to verify your email and log in to your
account.
</Text>
<Button href={url}>Verify your email</Button>
</MjmlColumn>
</MjmlSection>
</BaseLayout>
)
}
VerifyEmail.subject = 'Magic link'
export default VerifyEmail
Preview:
Using the verify email template to send a verification email from Auth.js
Open [...nextauth].tsx
and add the following code:
import sendMail from '../../../emails/index'
import Welcome from '../../../emails/Welcome'
//...
export const authOptions: NextAuthOptions = {
//...
providers: [
EmailProvider({
//...
async sendVerificationRequest({ identifier, url }) {
try {
await sendMail({
subject: 'Magic link',
to: identifier,
component: <Welcome url={url} />,
})
} catch (error) {
console.error(error)
}
},
}),
],
//...
}
export default NextAuth(authOptions)
As you can see, we are using the sendMail
function to send the verification email. The component
prop is the email template we created earlier.
Conclusion
And that's it! You can now send beautiful auth emails using Next.js, Mailing, and Postmark.