Top External Email Providers for Your Strapi Application
Tags: strapi, webdev, email, nextjs
Published: 2024-06-04 14:23:55

Email is one of the most critical communication channels between businesses and their users. It can be used to send notifications, updates, newsletters, offers, or other communications. [A global study](https://sendgrid.com/en-us/why-sendgrid) showed that 83% of people prefer to receive communications from businesses over email.

Going with an external email provider has many benefits, and Strapi offers a wide array of options and ways to integrate them into your application.


This article aims to simplify your decision-making process by gathering all the necessary resources in one place. We will compare these providers, helping you choose the one that best suits your application. 

Additionally, we will provide code examples and guide you through integrating this functionality into your Strapi projects, making the process more convenient and straightforward.

## What is Strapi?
Strapi is an open-source headless CMS (Content Management System) that allows you to quickly and easily create an API for content-rich applications. Unlike traditional CMS, it decouples the backend from the frontend, allowing you to pick whatever UI framework you're most comfortable with, meaning you can better create faster and more personalized experiences for your customers.

## External Email Providers
While Strapi provides us with powerful ways to manage content and user data, using an external email provider comes with several benefits.

### Benefits of Email Providers
* They are reliable as they invest heavily in infrastructure, anti-spam measures, and deliverability
* They are scalable: as your application grows, so too will the number of emails you send. 
* An external email provider has the ability to handle large email volumes without compromising on performance or deliverability, 
* They get rid of the need for your developers to manage email server infrastructure. 
* They also offer a lot of different features for you to take advantage of and follow best practices when it comes to security.

### How to choose

Strapi's flexibility allows us to combine it with a wide range of email service providers, such as **Mailgun**, **Resend**, **Sendgrid**, **Nodemailer**, and **AWS SES**. We'll review and compare the advantages of each.

There are many things to consider when selecting an email service provider. For instance, imagine an up-and-coming e-commerce platform experiencing rapid growth in its customer base and transactional email volume. In this case, it may want to go for a more reliable service, such as AWS SES, which will ensure reliable handling of increased email volume without compromising on deliverability and speed. 

On the other hand, let's consider a more content-focused website powered by Strapi, where personalised news letters and email campaigns are key to the business's success. In this case, a feature-rich solution like Sendgrid, with its segmentation, A/B testing, and campaign analytics, would be a great fit. This example underscores the importance of first understanding your project requirements and then aligning them with the most suitable provider, a strategy that can significantly enhance your email marketing efforts.

### Advantages of Using Strapi with Email Providers

Strapi provides a great content management system; we can easily pull in user-specific data, such as names or preferences, and inject them into our email templates to make them more engaging. Strapi is scalable and offers a user-friendly interface with built-in API capabilities, which will help streamline the development process and reduce the time and effort it would cost to build something similar with another framework such as [express.js](https://expressjs.com/).

Let's examine each provider individually to see what they offer and how they compare to each other.

## Resend Email Provider

First up, we have [Resend](https://www.resend.com/), which is an email service provider that helps optimise transactional emails and email campaigns. It offers a collection of tools to simplify the process of sending marketing emails, making sure they reach the correct recipients effectively and not the spam folder. With Resend's free plan, you can send 100 emails per day.

### Resend Features

Resend has a test mode, so you can experiment with their API without the risk of sending accidental emails. They also offer modular webhooks, so you can receive real-time notifications letting you know when emails are delivered, opened, bounced, or even if a link inside is clicked. Another great feature of Resend is that you can develop email templates with React, getting rid of the need to use confusing table layouts.

The paid version of Resend offers a multi-region option, which allows you to send emails from the region closest to your users, so you can be sure they receive your emails in a timely and efficient manner. They also offer a dedicated IP for those companies who wish to avoid a shared IP and maintain complete control over their reputation.

Resend also offers open and click tracking, which allows developers to track engagement and tune their sending approach. This allows you to identify which of your customers or users are most interested in receiving your messages.

Key features:

- Multi-language support.
- CRM integrations with Hubspot, ActiveCampaign, etc..
- Link tracking, open & click tracking.
- Behaviour-based subscriber segmentation.
- Automated welcome and follow-up flows.
- Inbox placement and spam testing.

## Strapi and Resend Integration
### Install Strapi
Create a folder that will contain the source code for the project. Open a terminal and navigate to a directory of your choice, and run the below commands:

```bash
mkdir strapi-email-tutorial
cd strapi-email-tutorial
```

Now, let's create our Strapi project with the command below:

```bash
npx create-strapi-app@latest strapi-email
```

You can enter `y` to proceed and select `quickstart`

Once that has finished installing, you should see a confirmation such as the below:
![install-strapi.png](https://api-prod.strapi.io/uploads/install_strapi_e81189dc93.png)

### Obtain Resend API Key
Now before we write any code, let's obtain an API key for Resend. Go to the following address: https://resend.com/overview, sign in, and get the API key; there should be an option to generate one on the dashboard.

Now navigate to the route of the strapi project in the terminal and run the following to install the [Strapi plugin for Resend](https://market.strapi.io/providers/strapi-provider-email-resend):

```bash
yarn add strapi-provider-email-resend
```

Copy the following code and replace with the code in the  `config/plugins.js`. Make sure to add the `RESEND_API_KEY` variable to your `.env` file, with the value being the key you generated with Resend. Also, use your normal email account for the `defaultFrom` and `defaultTo` fields.

```js
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'strapi-provider-email-resend',
      providerOptions: {
        apiKey: env('RESEND_API_KEY'), // Required
      },
      settings: {
        defaultFrom: 'YOUR_EMAIL_HERE',
        defaultReplyTo: 'YOUR_EMAIL_HERE',
      },
    }
  },    
});
```

### Generate Custom Email API
Now we have the Resend plugin setup in our project we should be able to use the package in one of our API's, let's first generate a custom API and write the code, navigate to the terminal and run the below command in the root directory:

```bash
yarn strapi generate
```

This will begin the process of generating our own custom API. Choose the API option, give it the name `email-test`, and select **"no"** when it asks us if this is for a plugin.

Inside the `src` directory, If we check the `api` directory in our code editor, we should see the newly created API for `email-test` with it's route, controller, and service.

![001-api-creation.png](https://api-prod.strapi.io/uploads/001_api_creation_f30834c9f3.png)

### Enable Public API Access
By default, Strapi requires authentication to query our API and receive information, but that is outside the scope of this tutorial. Instead, we will make our API publicly accessible. We can find more about authentication and REST API in this [blog post](https://strapi.io/blog/guide-on-authenticating-requests-with-the-rest-api).

![002-enable-strapi-api-public.png](https://api-prod.strapi.io/uploads/002_enable_strapi_api_public_78dde774bd.png)

Navigate to the Strapi admin dashboard, From the left sidebar, click on Settings. Again,  on the left panel under **USERS & PERMISSIONS PLUGIN**, click on **Roles**, then click on **Public** from the table on the right. Now scroll down, click on **Email-test**, and tick **Select all** then save in the top right which will allow us to hit this endpoint without authentication.

### Modify Custom Email Route
Now under the `src/api/email-test` directory, locate the `routes` directory. There you will find `email-test.js` file. Replace the code inside this file with the following:

```js
module.exports = {
  routes: [
    {
      method: "POST",
      path: "/email-test/exampleAction",
      handler: "email-test.exampleAction",
      config: {
        policies: [],
        middlewares: [],
      },
    },
  ],
};
```
### Modify Custom Email Controller
Change the code in the `src/api/controllers/email-test.js` file to the following:

```js
module.exports = {
  exampleAction: async (ctx, next) => {
    try {
      const res = await strapi
        .service("api::email-test.email-test")
        .emailService(ctx);
      ctx.body = res.message;
    } catch (err) {
      ctx.body = err;
    }
  },
};
```

### Modify Custom Email Service
Also, change the code in the `src/api/services/email-test.js` directory to the following:

```js
module.exports = ({ strapi }) => ({
  emailService: async (ctx) => {
    try {
      const input = ctx.request.body.data?.input;
      const emailTo = ctx.request.body.data?.emailTo;
      await strapi.plugins["email"].services.email.send({
        from: "onboarding@resend.dev",
        to: emailTo,
        subject: "Hello World",
        html: `<p>${input}</p>`,
      });

      return {
        message: "Email sent!",
      };
    } catch (err) {
      ctx.body = err;
    }
  },
});
```

You should now be able to test the Resend email integration with the following code in your terminal, make sure you replace `YOUR_EMAIL_HERE` with your actual email address.

```bash
curl -X POST \
  http://localhost:1337/api/email-test/exampleAction \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
        "input": "This is a test email to check the integration.",
        "emailTo": "YOUR_EMAIL_HERE"
    }
}'
```

## Sendgrid Email Provider

[Sendgrid](https://sendgrid.com/) focuses on email delivery, automation and real-time analytics it allows users to send transactional and marketing emails at scale, it offers a 99% deliverability rate and has AI-powered deliverability, and email marketing, email automation and multichannel advertising products. With Sengrids free plan, you can send 100 emails per day.

### Sendgrid Features

Key features include

- Dedicated IP addresses to improve deliverability
- Integrations with e-commerce platforms like shopify and BigCommerce
- A/B testing capabilities
- Automated workflows with templates
- Contact segmentation for targeted campaigns
- In-depth email and click analytics

### Sendgrid vs Resend

In terms of deliverability, Sendgrid provides dedicated IPs for improved sender reputation and inboxing; it has average industry deliverability rates compared to Resend, which heavily optimises campaigns for maximum inbox placement, maintaining exceptional IP reputations. Both platforms provide good deliverability that meets or exceeds industry standards.

When we look at Automation and workflow for campaigns both Sendgrid and Resend provide easy to use drag-and-drop workflow builders to create sequences and triggers. For multi-step campaigns, Resend seems to be the best at building conditional logic across workflows but Sendgrid also allows multi-path workflows. In terms of segmentation and targeting Resend has the strongest features for dynamically inserting subscriber data into emails, Sendgrid allows some personalisation. Sendgrid imposes contact limits whereas Resend allows unlimited segments.

Sendgrid seems to have the most integrations and plugins available, with extensive documentation, Resend has fewer out of the box integrations.

In terms of analytics Sendgrid has the most powerful segmentation capabilities for analyzing your email data, allowing you to deeply filter your reports, while Resend visual reports and insights are simplest to digest Sendgrid provides greater raw data access.

As a conclusion to this quick comparison between these two email providers I think Resend is best for beginners, with easy workflow automation, campaign building and visual reporting whereas Sendgrid provides the greatest email volume scalability and add-on integrations, It also offers robust targeting and analytics for experts.

## Strapi and Sendgrid Integration

We can use a [Strapi plugin](https://market.strapi.io/providers/@strapi-provider-email-sendgrid) to integrate Sendgrid just like we did with Resend, first of all let's remove the Resend integration, navigate to your terminal and run the below command in the root directory.

### Install Sendgrid Strapi Plugin
```bash
yarn remove strapi-provider-email-resend
```

With that package removed, run the below to install the [Sendgrid plugin](https://market.strapi.io/providers/@strapi-provider-email-sendgrid).

```bash
yarn add @strapi/provider-email-sendgrid
```

### Modify Plugin Configuration
Now navigate to your `config/plugins.js` file and replace the code in there with the below:

```js
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: "sendgrid",
      providerOptions: {
        apiKey: env("SENDGRID_API_KEY"), // Required
      },
      settings: {
        defaultFrom: "YOUR_EMAIL_HERE",
        defaultReplyTo: "YOUR_EMAIL_HERE",
      },
    },
  },
});
```

Make sure to head on over to [sendgrid](https://sendgrid.com/) and create a free account, then navigate to settings and create an API key.

### Add Sendgrid API Key to Environment Variable
You can then add it to your `.env` file so the above integration works.

```bash
SENDGRID_API_KEY=YOUR_SENDGRID_API_KEY
```
### Modify Email Service
Now restart the project and the only thing you will need to change is the `from` field in the `src/api/email-test/services/email-test.js` file as below:

```js
 await strapi.plugins["email"].services.email.send({
        from: "YOUR_EMAIL_HERE",
        to: email,
        subject: "Hello World",
        html: `<p>${input}</p>`,
      });
```

### Test Sendgrid Email Provider
Seeing that the rest of the code is in place from the previous Resend integration if you run the below code in the terminal it should send an email using Sendgrid.

```bash
curl -X POST \
  http://localhost:1337/api/email-test/exampleAction \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
        "input": "This is a test email to check the integration.",
        "emailTo": "YOUR_EMAIL_HERE"
    }
}'
```

## Nodemailer Email Provider

[Nodemailer](https://nodemailer.com/) is a module developed in 2010 to simplify email sending. It has a flexible and easy-to-use interface and utilizes various email services or SMTP servers, including EmailEngine. This self-hosted email gateway allows you to make REST requests against IMAP and SMTP servers. This makes Nodemailer more flexible, as it gives you a choice to use different email services or SMTP servers based on your requirements. Note that while it is free to use Nodemailer, you may incur costs depending on the email service you choose.

### Differentiation From Hosted Email Services

Nodemailer allows us to send emails directly from our Node applications. Hosted email service providers like Sendgrid, on the other hand, differ. For example, hosted email services provide a dedicated and reliable infrastructure, typically offer a broad range of features beyond sending basic emails, are easier to use, and will more often than not operate on some sort of subscription-based model.

So in comparison, just to recap, Nodemailer gives us flexibility in choosing the email transport method and supports various options: `SMTP`,`sendmail`, `Amazon SES`, and more. Nodemailer focuses on core email sending functionality, allowing developers to send emails programatically from their applications. It gives us some basic features like email composition, attachment support, and error handling.

### Strapi and NodeMailer Integration

For Nodemailer to work we will need to provide it with an `SMTP` service and the auth credentials, let's use `Ethereal` which is a fake `SMTP` service. navigate to - https://ethereal.email and click the button to create an Ethereal account.

![003-nodemailer-configuration.png](https://api-prod.strapi.io/uploads/003_nodemailer_configuration_afa9293341.png)

Now you should be directed to a page like the above, jot down the credentials somewhere as we will use these later.

### Install NodeMailer Strapi Plugin
Now navigate back to your terminal and go to the root directory. Remove the previous plugin with the following command:

```bash
yarn remove @strapi/provider-email-sendgrid
```

And add the Strapi n[odemailer plugin](https://www.npmjs.com/package/@strapi/provider-email-nodemailer) by running the below:

```bash
yarn add @strapi/provider-email-nodemailer
```

### Update Configuration
Once that has finished let's add the plugin integration code to the `config/plugins.js` file, remember you will need to create the `SMTP_USERNAME` and `SMTP_PASSWORD` variables in your .env file and fill their values with the info you obtained from ethereal mail:

```js
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST', 'smtp.ethereal.email'),
        port: env('SMTP_PORT', 587),
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```

### Update Email Service
Update the email code in the `src/api/email-test/services/email-test.js` file with the following:

```js
  await strapi.plugins["email"].services.email.send({
        from: "YOUR_ETHEREAL_MAIL",
        to: email,
        subject: "Hello World",
        html: `<p>${input}</p>`,
      });
```

Run the below code in your terminal to see Nodemailer in action remembering to replace the emailTo with your email:

### Test NodeMailer Email Provider 

```bash
curl -X POST \
  http://localhost:1337/api/email-test/exampleAction \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
        "input": "This is a test email to check the integration.",
        "emailTo": "YOUR_EMAIL_HERE"
    }
}'
```

As ethereal is a fake SMTP provider, it won't actually send the email, but you can navigate back to ethereal and look under the `Messages` tab (this tab captures all of the outgoing and incoming mail), and you will be able to see the outgoing email that Nodemailer just connected with ethereal to send, confirming that the integration was successful.

## AWS SES Email Provider

Amazon Simple Email Service (SES) is a cloud-based email service provided by Amazon Web Services. It allows you to send transactional, marketing, and notification emails, much like Resend and Sendgrid. It offers an extensive set of features, such as improved inbox deliverability with a virtual deliverability manager so you can reach inboxes instead of spam or junk, flexible deployment options such as shared or dedicated IP addresses, a console so you can view important analytics such as number of sends, opens, clicks, bounces, etc, and it supports all industry-standard authentication mechanisms.

### AWS SES Features

key features include

- Reliable Email Sending
- High Deliverability
- SMTP and API-based Sending
- Email Templates
- Bounce and Complaint Handling
- Email Analytics
- Dedicated IP Addresses
- Integration with AWS Services
- Cost-effective Pricing


In terms of pricing, Amazon SES will allow you to send 3000 messages per month for 12 months completely free. In comparison, Resend and Sendgrid offer the same amount of emails but don't give you a 12-month time period, suggesting you can stay on their free tier until you scale up. However,  upon closer inspection, Amazon's paid service is actually cheaper. 20,000 emails a month will cost you $2 per month, while with Resend or Sendgrid, that will set you back $20 per month. This suggests that if you intend to scale rapidly, Amazon would be a better choice.

I would say one of the main standout features of AWS SES is its ability to integrate with other services on the AWS platform. You can configure it to be used on a site hosted on EC2 and set up some custom notifications with Simple Notification Service (SNS), for example. It might also be worth mentioning if you plan to use AWS EC2 for your hosting. AWS gives you the first 62,000 emails per month absolutely free.

### Strapi and AWS SES Integration

Now to integrate this service with Strapi we can use a plugin but we will also need to create an AWS account to configure Amazon SES and get the correct credentials to connect.

First navigate to AWS at - https://aws.amazon.com create an account and then on the dashboard search for Amazon SES, click get started and then you should be directed to a dashboard like this 

![004-add-email-to-aws-ses.png](https://api-prod.strapi.io/uploads/004_add_email_to_aws_ses_cc0379bd8d.png)

You can just add your email address here, then click next.

![005-add-sending-domain-to-aws-ses.png](https://api-prod.strapi.io/uploads/005_add_sending_domain_to_aws_ses_87151d47c3.png)

Here you can just add the domain of your email and click next on all of the following options.

Then you can click in the top right dropdown and navigate to `security credentials` scroll down and click to create an access key then copy the Access key and the Secret somewhere safe.

### Install NodeMailer Strapi Plugin
Now you can navigate to the root of your project and remove the previous integration with the following command:

```bash
yarn remove @strapi/provider-email-nodemailer
```

And then add the [AWS SES Strapi plugin](https://market.strapi.io/providers/@strapi-provider-email-amazon-ses) by running the below command

```bash
yarn add @strapi/provider-email-amazon-ses
```

### Update Configuration
Navigate to `./config/plugins.js` and paste in the following integration code

```js
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'amazon-ses',
      providerOptions: {
        key: env('AWS_SES_KEY'),
        secret: env('AWS_SES_SECRET'),
        amazon: 'https://email.us-east-1.amazonaws.com',
      },
      settings: {
        defaultFrom: 'myemail@protonmail.com',
        defaultReplyTo: 'myemail@protonmail.com',
      },
    },
  },
});
```

### Update Email Service
Now add the AWS access and secret key you got earlier to the `.env` file with the relevant variable names.

And in `src/api/email-test/services/email-test.js` file, you will just need to change the email from the previous ethereal email to the one you used for SES:

```js
  await strapi.plugins["email"].services.email.send({
        from: "YOUR_EMAIL_HERE",
        to: email,
        subject: "Hello World",
        html: `<p>${input}</p>`,
      });
```

Now that we've set up the integration we can use this curl command in the terminal to simulate the api call and watch Amazon SES in action 

### Test AWS SES Provider
```bash
curl -X POST \
  http://localhost:1337/api/email-test/exampleAction \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
        "input": "This is a test email to check the integration.",
        "emailTo": "YOUR_EMAIL_HERE"
    }
}'
```

## Mailgun Email Provider

Like the other email automation services we have seen so far, [Mailgun](https://www.mailgun.com/) offers all of the usual features, such as email sending, tracking, and analytics. What sets it apart from the crowd is its email validation service, which ensures that the email addresses you're sending mail to actually exist, this helps overall email deliverability. For instance, if you integrated this into a contact form, you could use this feature for real-time validation, and the user would be quickly notified if they entered an invalid email address.

Mailgun offers a free plan which allows you to send up to 5000 emails per month (to five authorized users of your choice) but then on the paid plan it jumps to 50,000 emails per month priced at $35 per month, clearly Mailgun free tier has limited features and it's paid plan is a little on the pricey side.

### Mailgun Features

- Email sending via API or SMTP integration
- Email parsing and routing for inbound emails
- Email validation to maintain a clean email list
- Comprehensive email tracking and analytics
- Customizable email templates for personalized campaigns
- A/B testing to optimize email content and performance
- Developer-friendly APIs, SDKs, and libraries
- Scalable infrastructure for handling large email volumes
- Compliance with email regulations (e.g., GDPR, CAN-SPAM)
- Security features such as SPF/DKIM authentication and TLS encryption

### Strapi and Mailgun Integration

To integrate Mailgun we can use the Strapi plugin to proceed, but first let's generate the api key we will need to connect to mailgun, head over to the following - https://www.mailgun.com and click "Get started for free" in the top right for Mailgun login.

![006-mailgun-homepage.png](https://api-prod.strapi.io/uploads/006_mailgun_homepage_6b5db05855.png)

Go through the mailgun login or account creation process and once that's done you should be able to scroll down on the dashboard and select your domain.

Then if you click the dropdown for your account in the top right and click on "API security", and then you can scroll down to see your api key.

### Install Mailgun Strapi Plugin
Now navigate to the root of your project in the terminal and remove the previous plugin with the below command.

```bash
yarn remove @strapi/provider-email-amazon-ses
```

And add the [Mailgun Strapi plugin](https://market.strapi.io/providers/@strapi-provider-email-mailgun) with the following:

``` bash
yarn add @strapi/provider-email-mailgun
```

### Update Configuration
Navigate to `./config/plugins.js` and paste in the following integration code

``` js
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'mailgun',
      providerOptions: {
        key: env('MAILGUN_API_KEY'), // Required
        domain: env('MAILGUN_DOMAIN'), // Required
        url: env(https://api.mailgun.net'), //Optional. If domain region is Europe use 'https://api.eu.mailgun.net'
      },
      settings: {
        defaultFrom: 'myemail@protonmail.com',
        defaultReplyTo: 'myemail@protonmail.com',
      },
    },
  }
});
```

Making sure you add the relevant variable to your `.env` file.

Now you should be all set to test out the integration by running the below code in your terminal

### Test Mailgun Email Provider
```bash
curl -X POST \
  http://localhost:1337/api/email-test/exampleAction \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
        "input": "This is a test email to check the integration.",
        "emailTo": "YOUR_EMAIL_HERE"
    }
}'
```

## Choosing the Right Email Provider

First of all, thanks to the flexibility of Strapi, there was a quick and easy way to integrate every email provider we looked at, so complexity in integration, at least where your Strapi projects are concerned, isn't an issue. All the options we looked at are great, and the one you pick will ultimately come down to your priorities and the number of emails you're sending.

Amazon SES stands out if cost-effectiveness is your primary consideration, especially if you're hosting on AWS infrastructure like an EC2 instance and anticipate rapid scaling of your service. If your focus is on enhancing your marketing efforts, then the choice is between Sendgrid and Resend, both of which offer similar features. Resend, with its user-friendly interface and easy-to-understand analytics dashboard, may be more suitable for beginners. On the other hand, Sendgrid, with its more complex and detailed features, provides more granular data.

If customizability is important and you're only concerned with basic send and receive functionality, then Nodemailer is a good option. Lastly, we have Mailgun, which isn't the cheapest solution and doesn't have the most features; if email validation is essential, it could be an option.

## Conclusion

To recap, the benefits of integrating with an external email provider are numerous and include the following: enhanced email functionality, improved deliverability, scalability, analytics, and customization.

This article will help you select the right email provider for your product or business. If you still need to decide, experiment with different providers and see what works best.

## Additional Resources
* [Github link](https://github.com/gitChimp88/strapi-email) to the complete code.