Easily send emails in Strapi with any provider

Last updated

Antonio Ufano avatar

Antonio Ufano

Sending emails is a fundamental feature in most projects. From welcoming new users to sending notifications and reminders, it's something that I find myself doing in every project.

I've been using Strapi for a few months now as it allows me to create APIs easily and fast and, even though it includes a default plugin to send emails out the box, it's not the best option to use in Production. There are multiple plugins for different email providers but in this article, I'll show you how to use a plugin that works with any provider.

Why you shouldn't Strapi's default email plugin

Why do we need to install a new plugin if Strapi has one out of the box? As they mention in the documentation, Strapi uses sendmail as a default provider, which basically means that the emails are sent directly from the local server running Strapi.

You might use this during development but in Production it can cause you some issues:

  • It's not 100% reliable
  • Common mail servers, like Gmail, Outlook and Yahoo will block your emails if they are not being sent from a trusted server.
  • Your server might not have sendmail installed
  • Sendmail won't probably work if you are deploying your Strapi application with Docker

To avoid these issues, it's better to use an external provider. In the Strapi documentation they have an example using Sendgrid with its own specific plugin. Although it's a great platform, Sendgrid's free tier is very limited (only 100 emails/day) so I prefer to use SendinBlue (free 300 emails/day) or for more email demanding projects, ElasticEmail ($0.09 per 1000 emails).

Although there is a specific plugin for SendinBlue, I don't like the idea of my application depending on one specific third party like that and I'm not sure if I'll be using the same provider forever, so I prefer to use a plugin that is provider agnostic. And what do most email providers have in common? They all support the SMTP protocol, so that's what we'll use.

For this article, I'd assume we'll be using SendinBlue so go ahead and create a free account. You can find the SMTP details in your account settings > SMTP & API.

Sendinblue SMTP connection details

Plugin install and setup

The first thing you'll need is a scaffolded Strapi project. You can check how to create one in this article.

The plugin we're going to use is strapi-provider-email-nodemailer and, as I mentioned I choose this one for multiple reasons:

  • It's provider agnostic
  • Uses SMTP protocol
  • Super easy to configure and use
  • Migrating to a different provider is super simple

To install it, run npm i strapi-provider-email-nodemailer. To configure it I recommend to use an .env file as your server details will probably be different in DEV and PROD. To checkout how to use .env files in Strapi, check this section of the docs.

In our .env file we'll add the following variables:

EMAIL_PROVIDER=nodemailer
EMAIL_SMTP_HOST=smtp.zzzz.zzzzz
EMAIL_SMTP_PORT=587
EMAIL_SMTP_USER=xxXXXXxxxxXXX
EMAIL_SMTP_PASS=yyyYYYYYyyyYYYY
EMAIL_ADDRESS_FROM=aaaaaa@bbbbbb.com
EMAIL_ADDRESS_REPLY=ccccccc@dddddd.com

Sendinblue's SMTP host is smtp-relay.sendinblue.com and port is 587.

Next step is to configure the plugin in the config/plugins.js file:

// File: config/plugins.js

module.exports = ({ env }) => ({
  // ...
  email: {
    provider: env('EMAIL_PROVIDER'),
    providerOptions: {
      host: env('EMAIL_SMTP_HOST', 'smtp.example.com'),
      port: env('EMAIL_SMTP_PORT', 587),
      auth: {
        user: env('EMAIL_SMTP_USER'),
        pass: env('EMAIL_SMTP_PASS'),
      },
    },
    settings: {
      defaultFrom: env('EMAIL_ADDRESS_FROM'),
      defaultReplyTo: env('EMAIL_ADDRESS_REPLY'),
    },
  },
  // ...
})

As you can see, the configuration is pretty straight forward and we just have to assign the server and authentication details that we included in the env before.

If you don't want to use an env file, you can populate these variables using process.env.YOUR_ENV_VARIABLE instead of env('YOUR_ENV_VARIABLE') or, if you're testing locally, directly assigning the values but remember not to commit these to your repository for security reasons.

Sending emails

To make this example as simple as possible, I'll create an endpoint in our API that automatically sends an email. We'll create the following files inside api folder:

  • /api/email/config/routes.json
// /api/email/config/routes.json
{
  "routes": [
    {
      "method": "POST",
      "path": "/emails",
      "handler": "Email.send",
      "config": {}
    }
  ]
}

This will create a new POST endpoint /emails in our API, and the requests will be handled by the send method inside the Email controller, which we will create next:

  • /api/email/controllers/Email.js
// File /api/email/controllers/Email.js
'use strict'

/**
 * Read the documentation () to implement custom controller functions
 */

module.exports = {
  /**
   * Sends an email to the recipient in the body of the request
   */
  send: async (ctx) => {
    const body = ctx.request.body
    const sendTo = body.email
    strapi.log.debug(`Trying to send an email to ${sendTo}`)

    try {
      const emailOptions = {
        to: sendTo,
        subject: 'This is a test',
        html: `<h1>Welcome!</h1><p>This is a test HTML email.</p>`,
      }
      await strapi.plugins['email'].services.email.send(emailOptions)
      strapi.log.debug(`Email sent to ${sendTo}`)
      ctx.send({ message: 'Email sent' })
    } catch (err) {
      strapi.log.error(`Error sending email to ${sendTo}`, err)
      ctx.send({ error: 'Error sending email' })
    }
  },
}

The send method receives a POST request with the email in the body. We create an emailOptions object that contains the properties for destination address (to), subject and html as the body of the email. Then we just have to use the the strapi.plugins['email'].services.email.send method and pass it the emailOptions object.

If you need to add attachements, bcc or other email options, you can check the nodemailer message configuration here. You'd just need to add the options you need in the emailOptions object 😉

Now if we start our Strapi application with npm run develop and send a POST request to /emails with Postman or cURL, our email will be sent 📬

# Send POST request to /emails via cURL

curl --location --request POST 'localhost:1337/emails' \
--header 'Content-Type: application/json' \
--data-raw '{"email": "example@email.com"}'

Conclusion

This is a very basic example to show you how to programmatically send emails with Strapi via SMTP. In my case I normally trigger emails in cron jobs or in an authentication protected endpoints after users do a certain action.

Important: You shouldn't have a public endpoint in your API that triggers emails as it can be easily exploited and you could be charged by your email provider.

I like using nodemailer because it's provider agnostic and it allows me to easily change providers by just changing the server and credential details in my env file. In addition, it supports Amazon SES transport so you can use that option. You can find more info about how to use nodemailer with SES here.

I hope you find this article useful.

Happy coding!

If you enjoyed this article consider sharing it on social media or buying me a coffee ✌️

Oh! and don't forget to follow me on Twitter where I share tons of dev tips 🤙

Other articles that might help you

my projects

Apart from writing articles in this blog, I spent most of my time working on my personal projects.

lifeboard.app logo

theLIFEBOARD.app

theLIFEBOARD is a weekly planner that helps people achieve their goals, create new habits and avoid burnout. It encourages you to plan and review each week so you can easily identify ways to improve your productivity while keeping track of your progress.

Request early access
soliditytips.com logo

SolidityTips.com

I'm very interested in blockchain, smart contracts and all the possiblilities chains like Ethereum can bring to the web. SolidityTips is a blog in which I share everything I learn about Solidity and Web3 development.

Check it out if you want to learn Solidity
quicktalks.io logo

Quicktalks.io

Quicktalks is a place where indie hackers, makers, creators and entrepreneurs share their knowledge, ideas, lessons learned, failures and tactics they use to build successfull online products and businesses. It'll contain recorded short interviews with indie makers.

Message me to be part of it