Skip to content

Configure Strapi 5 Email Provider & Workflow Notifications

Learn how to set up Strapi 5’s native email plugin, choose a provider (SendGrid or Nodemailer), and trigger automatic email alerts when content moves through a review workflow or is published.

By the Revisionary team · · 4 min read

Ai interface on a glowing keyboard
Photo by Zulfugar Karimov on Unsplash

Strapi 5 ships with a built‑in Email plugin that can send transactional messages via SMTP or popular third‑party services. By configuring the provider once and adding a small Document Service middleware, you can automatically notify authors, reviewers, or external stakeholders each time an entry passes a workflow stage or is finally published.

1. Why configure email for workflow notifications?

Content approval in Strapi Enterprise is driven by Review Workflows. Teams often need a clear signal—usually an email—when a piece of content reaches a required stage (e.g., Ready to review) or when it goes live. Without automation, editors must manually ping colleagues, which defeats the purpose of a structured workflow.

MacBOok Pro beside brown mug
Photo by Artem Sapegin on Unsplash

2. Install the Email plugin (built‑in)

The Email plugin is part of the core Strapi 5 distribution; no extra npm package is required. After creating a Strapi project (npx create-strapi-app my‑project@5.x), the plugin is already registered. Verify it is enabled in config/plugins.ts:

js
module.exports = ({ env }) => ({
  // other plugins …
  email: {
    // configuration will be added here
  },
});

If the email key is missing, add it as shown above.

3. Choose and configure a provider

Strapi supports several providers out of the box. The two most common are SendGrid (API‑based) and Nodemailer (SMTP). Choose the one that matches your infrastructure.

3.1 SendGrid configuration

js
// config/plugins.ts
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'sendgrid',
      providerOptions: {
        apiKey: env('SENDGRID_API_KEY'),
      },
      settings: {
        defaultFrom: 'no-reply@example.com',
        defaultReplyTo: 'support@example.com',
        testAddress: 'test@example.com',
      },
    },
  },
});

Set the environment variable SENDGRID_API_KEY in your .env file.

3.2 Nodemailer (SMTP) configuration

js
// config/plugins.ts
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: env.int('SMTP_PORT', 587),
        secure: false, // true for 465
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'no-reply@example.com',
        defaultReplyTo: 'support@example.com',
      },
    },
  },
});

Populate SMTP_HOST, SMTP_USERNAME, and SMTP_PASSWORD in .env.

3.3 Rate‑limit (optional)

If you expect bursty traffic, enable the built‑in rate‑limit:

js
email: {
  config: {
    // provider config …
    ratelimit: {
      enabled: true,
      interval: 5,
      max: 5,
      delayAfter: 1,
      timeWait: 1,
      prefixKey: '${userEmail}',
      whitelist: [],
    },
  },
},

This prevents accidental spamming of the same address.

4. Test the configuration

A quick sanity check can be run from a Strapi controller, a custom route, or the REPL:

js
await strapi.plugins['email'].services.email.send({
  to: 'dev@example.com',
  subject: 'Strapi email test',
  text: 'The email plugin is working.',
  html: '<p>The email plugin is working.</p>',
});

If the message arrives, the provider is correctly set up.

5. Review Workflows – the trigger point

Strapi Enterprise lets you define a pipeline of stages (e.g., To do → Ready to review → Approved → Published). A content type can be linked to a specific workflow via the admin UI (Settings → Review Workflows). The key setting for notifications is the required stage for publishing, which you can set to “Approved”.

6. Hooking into the publish action with Document Service middleware

The Document Service replaces legacy lifecycle hooks. Middleware receives a context object that tells you which content type (uid) and which action (action) is being performed.

6.1 Create a middleware file

Create src/middlewares/publish-notifications.js:

js
module.exports = {
  // Called once when the server boots
  register({ strapi }) {
    strapi.documents.use(async (context, next) => {
      // Run the core action first (create, update, publish, …)
      const result = await next();

      // Post‑processing – only act on publish events for the chosen content type
      if (
        context.uid === 'api::article.article' &&
        context.action === 'publish'
      ) {
        // Load the full entry, including the author (createdBy) and any reviewers
        const entry = await strapi
          .documents('api::article.article')
          .findOne({
            documentId: context.params.documentId,
            populate: {
              createdBy: { fields: ['email', 'firstname', 'lastname'] },
              // Assuming a relation "reviewer" exists on the model
              reviewer: { fields: ['email', 'firstname'] },
            },
          });

        if (entry) {
          const { createdBy, reviewer, title } = entry;
          const recipients = [];
          if (createdBy?.email) recipients.push(createdBy.email);
          if (reviewer?.email) recipients.push(reviewer.email);

          // Send a notification to each stakeholder
          await Promise.all(
            recipients.map((email) =>
              strapi.plugins['email'].services.email.send({
                to: email,
                subject: `Article published: ${title}`,
                text: `Hi,\n\nThe article “${title}” has just been published.`,
                html: `<p>Hi,</p><p>The article <strong>${title}</strong> has just been published.</p>`,
              })
            )
          );
        }
      }

      return result;
    });
  },
};

6.2 Register the middleware

Add the file path to config/middlewares.js (or config/middlewares.ts if you use TypeScript):

js
module.exports = [
  // …other middlewares
  { name: 'global::publish-notifications', config: {} },
];

Strapi will now execute the code after every successful publish of an article entry.

7. Sending templated emails (optional polish)

If you prefer richer content, use sendTemplatedEmail. Place a Lodash template file under src/email-templates/article-published.js:

js
module.exports = {
  subject: 'New article published: <%= entry.title %>',
  html: `<h1><%= entry.title %></h1><p>Author: <%= author.firstname %> <%= author.lastname %></p>`,
  text: 'A new article has been published: <%= entry.title %>',
};

Then call it from the middleware:

js
const template = require('../email-templates/article-published');
await strapi.plugins['email'].services.email.sendTemplatedEmail(
  { to: email },
  template,
  { entry, author: createdBy }
);

This keeps the formatting logic separate from business logic.

8. Using the Notifier plugin for in‑admin alerts (optional)

If you want a UI banner in addition to email, install the community strapi-plugin-notifier (downloaded as a zip, not via npm). After installing, configure it in config/plugins.ts:

js
module.exports = ({ env }) => ({
  notifier: {
    config: {
      enabled: true,
      // You can restrict broadcasting to specific roles
    },
  },
});

From the middleware you can then broadcast a message:

js
await strapi
  .plugin('notifier')
  .service('notifier')
  .broadcast({
    title: 'Article Published',
    message: `The article “${title}” is now live.`,
    type: 'info',
  });

Admins will see the toast notification in the top‑right corner of the admin UI.

9. Environment‑specific overrides

For development you might want to use a local SMTP server (e.g., Mailhog) and for production a real provider. Create config/env/development/plugins.ts and config/env/production/plugins.ts with the respective email block. Strapi automatically merges the environment file over the base configuration.

10. Verify the whole flow

  1. Create a new article in the admin UI – it starts in the Draft stage.
  2. Move the entry to Ready to review – no email is sent because the middleware only watches publish.
  3. Advance the workflow to the required stage (e.g., Approved).
  4. Press Publish. The middleware runs, fetches the entry, and sends an email to the author and reviewer. If the Notifier plugin is installed, an in‑admin toast appears as well.
  5. Check the Audit log (/docs/reference/audit-log) to see the entry.publish event recorded.

11. Common pitfalls & troubleshooting

SymptomLikely causeFix
No email receivedProvider credentials missing or wrongVerify SENDGRID_API_KEY or SMTP env vars; test with the manual send call from Section 4
Middleware not executedMiddleware not registered or UID mismatchEnsure config/middlewares.js includes the file and that context.uid matches the API UID (api::article.article).
Duplicate emails on rapid publishesRate‑limit disabledEnable ratelimit.enabled in the provider config.
Email content shows raw <%= %> placeholdersUsed send instead of sendTemplatedEmailSwitch to sendTemplatedEmail and pass a data object.
a close up of a server's nameplates on the side of a
Photo by Marc PEZIN on Unsplash

12. Next steps

  • Add more granular notifications (e.g., on stage change) by listening to entry.update events and checking the workflowStage field.
  • Integrate with external ticketing systems via webhooks (Admin → Settings → Webhooks) if you need Slack or Jira alerts.
  • Secure the email service by restricting API keys to the least‑privileged scope and rotating them regularly.

By configuring the built‑in Email plugin and adding a few lines of Document Service middleware, you turn Strapi 5’s Review Workflows into a fully automated approval pipeline. Editors get immediate feedback, stakeholders stay informed, and your publishing process becomes both faster and auditable.

For deeper customization, see the official Strapi Email documentation and the Review Workflows guide.

TagsStrapi 5EmailWorkflowNotificationsReview WorkflowsDocument Service

Sources

  1. Strapi Email plugin documentation
  2. Strapi Review Workflows feature guide
  3. Lifecycle hooks and Document Service middleware guide
  4. Strapi Notifier plugin marketplace page
  5. Strapi Email configuration – Nodemailer provider
  6. Strapi Email configuration – SendGrid provider

The Revisionary team

Developers who build Revisionary, a version history plugin for Strapi 5. We write about Strapi, web development, AI and application security.

This article was written with the help of AI.

All articles