Skip to content

escwxyz/payload-email-template

Repository files navigation

Payload Email Template Plugin πŸš€

npm version npm downloads MIT License


A powerful, visual, and block-based email template builder plugin for Payload CMS β€” built on top of React Email. Design beautiful, dynamic, and localized email templates with ease! ✨


✨ Features

  • 🧩 Visual, block-based email template builder (no raw JSX required)
  • πŸ—οΈ Custom blocks: Heading, Button, Container, Image, Row, Section, Text, and more
  • πŸ”§ Dynamic macros: Variables, functions, dates, conditions, loops, and config values
  • πŸ‘€ Preview: See your email as you build, with device and zoom controls
  • 🌍 Localization: Localize templates and content
  • πŸ”Œ API endpoints: Generate both HTML and PlainText before sending your email

πŸ“¦ Installation

pnpm add payload-email-template
# or
yarn add payload-email-template
# or
npm install payload-email-template

πŸš€ Getting Started

Add the plugin to your Payload config in the plugins array:

import { emailTemplatePlugin } from 'payload-email-template'

export default buildConfig({
  // ...other config
  plugins: [
    emailTemplatePlugin({
      enabled: true,
      imageCollectionSlug: 'media', // (optional) collection for image uploads
      previewBreakpoints: [
        // (optional) default breakpoints
        { name: 'mobile', label: 'Mobile', width: 375, height: 667 },
        { name: 'desktop', label: 'Desktop', width: 1440, height: 900 },
      ],
      disableStyle: false, // (optional) allow custom style overrides, default: false
      macros: {
        // (optional) dynamic content for variables, functions, and config
        variables: {
          companyName: 'Your Company',
          user: { firstName: 'John', lastName: 'Doe' },
        },
        functions: {
          greet: (name) => `Hello, ${name}!`,
          formatPrice: (price) => `$${price.toFixed(2)}`,
        },
        config: {
          appName: 'My App',
          version: '1.0.0',
        },
      },
      // ...other options
    }),
  ],
})

πŸ–ΌοΈ Demo

Demo 1

Demo 2


βš™οΈ Plugin Options

Option Type Default Description
enabled boolean true Enable/disable the plugin
imageCollectionSlug string 'media' Collection slug for image uploads
previewBreakpoints array see example Device preview sizes for the preview tab
disableStyle boolean false Disable custom style overrides
macros object {} Dynamic content configuration (variables, functions, config)
endpointAccess Access ({req}) => Boolean(req.user) Default access control for the /api/email-templates/:id/generate endpoint
collectionAccess Access { read: ({req}) => Boolean(req.user) } Default access control for email-templates collection

πŸ› οΈ Usage

🧱 Blocks

Configure blocks (Heading, Button, Container, etc.) to build your template. Each block has configurable fields (content, style, alignment, etc.). Blocks can be nested for complex layouts.

🌍 Localization

If you enable localization in your Payload config, the plugin will automatically make text-related template fields localizable.

πŸ‘€ Preview

The template can be previewed in the Preview tab. You can also use the controls to toggle mode, device, and zoom.


πŸ”Œ API Endpoints

Generate Email Template

You can trigger rendering the email template by sending a POST request to the following endpoint:

POST /api/email-templates/:id/generate

You will receive both html and plainText versions of the template:

{
  "html": "<html>...</html>",
  "plainText": "..."
}

Then you can send it via your email provider.


βš™ Local Api

Generate Email Template

It's also possible to render the email template by calling renderEmailTemplate directly in the back-end, skipping the http request in that case.

import { renderEmailTemplate } from "payload-email-template"

// const emailTemplate = await req.payload.find({
//   collection: 'email-templates',
//   ...
// })

const html = await renderEmailTemplate({
  data: emailTemplate,
  locale: 'en',
  format: 'html',
  macroContext: {
    variables: { ... },
    functions: { ... },
    config: { ... }
  }
})

πŸ”§ Macros

The plugin supports powerful dynamic content through macros that can be used in email subjects, headings, and text blocks.

Macro Types

1. Variables - {{variableName}}

Access data from your macro configuration:

{{companyName}} β†’ "Acme Corporation"
{{user.firstName}} β†’ "John"

2. Config Values - {{@config('key')}}

Access plugin configuration values:

{{@config('appName')}} β†’ "My Awesome App"
{{@config('version')}} β†’ "1.0.0"

3. Date Functions - {{@date('format')}}

Format current date and time:

{{@date('YYYY-MM-DD')}} β†’ "2024-01-15"
{{@date('MMMM Do, YYYY')}} β†’ "January 15th, 2024"

4. Functions (Server-side only)

Transform data with custom functions:

{{@uppercase('hello')}} β†’ "HELLO"
{{@greet('John')}} β†’ "Hello, John!" (if configured)

5. Conditional Content

Show content based on conditions:

  • Set up conditions in the macro block interface
  • Define content for true/false scenarios
  • Useful for personalized content

6. Loops

Repeat content for data collections:

  • Configure collection data source
  • Define template for each item
  • Great for product lists, etc.

Usage Locations

βœ… Email Subjects: "Welcome to {{companyName}}, {{user.firstName}}!"

βœ… Heading Blocks: Mix text, links, and macros in headings

βœ… Text Blocks: Inline macros alongside regular text and links

βœ… Macro Blocks: Dedicated blocks for complex conditions and loops

Runtime Context

You can also pass runtime macro context when generating emails:

// POST /api/email-templates/:id/generate
{
  "macroContext": {
    "variables": {
      "user": { "firstName": "Jane" },
      "orderTotal": "$99.99"
    }
  }
}

Runtime context takes precedence over plugin configuration.


🀝 Contributing

Contributions are welcome! Please open issues or pull requests for bug fixes, features, or documentation improvements.


πŸ“„ License

MIT

About

A Payload CMS plugin to build email templates based on React Email

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Contributors 4

  •  
  •  
  •  
  •