The Email feature enables Strapi applications to send emails from a server or an external provider.
Configuration
Most configuration options for the Email feature are handled via your Strapi project's code. The Email feature is not configurable in the admin panel, however users can test email delivery if it has been setup by an administrator.
Admin panel settings
Path to configure the feature: Settings > Email feature > Configuration


In the Configuration interface, only the email address field under "Test email delivery" is modifiable by users. A Send test email button sends a test email.
This page is only visible if the current role has the "Access the Email Settings page" permission enabled (see RBAC feature documentation for more information):


Code-based configuration
The Email feature requires a provider and a provider configuration in the config/plugins.js|ts
file. See providers for detailed installation and configuration instructions.
Sendmail is the default email provider in the Strapi Email feature. It provides functionality for the local development environment but is not production-ready in the default configuration. For production stage applications you need to further configure Sendmail
or change providers.
Email configuration options
Plugins configuration are defined in the config/plugins.js
file or config/plugins.ts
file. Please refer to providers for detailed provider-specific installation and configuration instructions.
Option | Type | Description | Default Value | Notes |
---|---|---|---|---|
provider | string | The email provider to use. | sendmail | Required |
providerOptions | object | The email provider options. | {} | Optional |
providerOptions.apiKey | string | The API key for the email provider. | '' | Optional |
settings | object | The email settings. | {} | Optional |
settings.defaultFrom | string | The default email address to use as the sender. | '' | Optional |
settings.defaultReplyTo | string | The default email address to use as the reply-to address. | '' | Optional |
ratelimit | object | The email rate limit settings. | {} | Optional |
ratelimit.enabled | boolean | Whether to enable rate limiting. | true | Optional |
ratelimit.interval | string | The interval for rate limiting in minutes. | 5 | Optional |
ratelimit.max | number | The maximum number of requests allowed during the interval. | 5 | Optional |
ratelimit.delayAfter | number | The number of requests allowed before rate limiting is applied. | 1 | Optional |
ratelimit.timeWait | number | Time to wait before responding to a request (in milliseconds). | 1 | Optional |
ratelimit.prefixKey | string | The prefix for the rate limit key. | ${userEmail} | Optional |
ratelimit.whitelist | array(string) | Array of IP addresses to whitelist from rate limiting. | [] | Optional |
ratelimit.store | object | Rate limiting storage location and for more information please see the koa2-ratelimit documentation. | MemoryStore | Optional |
Providers
The Email feature can be extended via the installation and configuration of additional providers.
Providers add an extension to the core capabilities of the plugin, for example to use Amazon SES for emails instead of Sendmail.
There are both official providers maintained by Strapi — discoverable via the Marketplace — and many community maintained providers available via npm.
A provider can be configured to be private to ensure asset URLs will be signed for secure access.
Installing providers
New providers can be installed using npm
or yarn
using the following format @strapi/provider-<plugin>-<provider> --save
.
For example, to install the Sendgrid provider:
- Yarn
- NPM
yarn add @strapi/provider-email-sendgrid
npm install @strapi/provider-email-sendgrid --save
Configuring providers
Newly installed providers are enabled and configured in the /config/plugins
file. If this file does not exist you must create it.
Each provider will have different configuration settings available. Review the respective entry for that provider in the Marketplace or npm to learn more.
The following is an example configuration for the Sendgrid provider:
- JavaScript
- TypeScript
module.exports = ({ env }) => ({
// ...
email: {
config: {
provider: 'sendgrid', // For community providers pass the full package name (e.g. provider: 'strapi-provider-email-mandrill')
providerOptions: {
apiKey: env('SENDGRID_API_KEY'),
},
settings: {
defaultFrom: 'juliasedefdjian@strapi.io',
defaultReplyTo: 'juliasedefdjian@strapi.io',
testAddress: 'juliasedefdjian@strapi.io',
},
},
},
// ...
});
export default ({ env }) => ({
// ...
email: {
config: {
provider: 'sendgrid', // For community providers pass the full package name (e.g. provider: 'strapi-provider-email-mandrill')
providerOptions: {
apiKey: env('SENDGRID_API_KEY'),
},
settings: {
defaultFrom: 'juliasedefdjian@strapi.io',
defaultReplyTo: 'juliasedefdjian@strapi.io',
testAddress: 'juliasedefdjian@strapi.io',
},
},
},
// ...
});
- When using a different provider per environment, specify the correct configuration in
/config/env/${yourEnvironment}/plugins.js|ts
(See Environments). - Only one email provider will be active at a time. If the email provider setting isn't picked up by Strapi, verify the
plugins.js|ts
file is in the correct folder. - When testing the new email provider with those two email templates created during strapi setup, the shipper email on the template defaults to
no-reply@strapi.io
and needs to be updated according to your email provider, otherwise it will fail the test (See Configure templates locally).
Configuration per environment
When configuring your provider you might want to change the configuration based on the NODE_ENV
environment variable or use environment specific credentials.
You can set a specific configuration in the /config/env/{env}/plugins.js|ts
configuration file and it will be used to overwrite the default configuration.
Creating providers
To implement your own custom provider you must create a Node.js module.
The interface that must be exported depends on the plugin you are developing the provider for. The following is a template for the Email feature:
- JavaScript
- TypeScript
module.exports = {
init: (providerOptions = {}, settings = {}) => {
return {
send: async options => {},
};
},
};
export {
init: (providerOptions = {}, settings = {}) => {
return {
send: async options => {},
};
},
};
In the send function you will have access to:
providerOptions
that contains configurations written inplugins.js|ts
settings
that contains configurations written inplugins.js|ts
options
that contains options you send when you call the send function from the email plugin service
You can review the Strapi-maintained providers for example implementations.
After creating your new provider you can publish it to npm to share with the community or use it locally for your project only.
Local providers
If you want to create your own provider without publishing it on npm you can follow these steps:
- Create a
providers
folder in your application. - Create your provider (e.g.
/providers/strapi-provider-<plugin>-<provider>
) - Then update your
package.json
to link yourstrapi-provider-<plugin>-<provider>
dependency to the local path of your new provider.
{
...
"dependencies": {
...
"strapi-provider-<plugin>-<provider>": "file:providers/strapi-provider-<plugin>-<provider>",
...
}
}
- Update your
/config/plugins.js|ts
file to configure the provider. - Finally, run
yarn
ornpm install
to install your new custom provider.
Private providers
You can set up a private provider, meaning that every asset URL displayed in the Content Manager will be signed for secure access.
To enable private providers, you must implement the isPrivate()
method and return true
.
In the backend, Strapi generates a signed URL for each asset using the getSignedUrl(file)
method implemented in the provider. The signed URL includes an encrypted signature that allows the user to access the asset (but normally only for a limited time and with specific restrictions, depending on the provider).
Note that for security reasons, the content API will not provide any signed URLs. Instead, developers using the API should sign the urls themselves.
Usage
The Email feature uses the Strapi global API, meaning it can be called from anywhere inside a Strapi application, either from the back-end server itself through a controller or service, or from the admin panel, for example in response to an event (using lifecycle hooks).
Sending emails with a controller or service
The Email feature has an email
service that contains 2 functions to send emails:
send()
directly contains the email contents,sendTemplatedEmail()
consumes data from the Content Manager to populate emails, streamlining programmatic emails.
Using the send()
function
To trigger an email in response to a user action add the send()
function to a controller or service. The send function has the following properties:
Property | Type | Format | Description |
---|---|---|---|
from | string | email address | If not specified, uses defaultFrom in plugins.js . |
to | string | email address | Required |
cc | string | email address | Optional |
bcc | string | email address | Optional |
replyTo | string | email address | Optional |
subject | string | - | Required |
text | string | - | Either text or html is required. |
html | string | HTML | Either text or html is required. |
The following code example can be used in a controller or a service:
await strapi.plugins['email'].services.email.send({
to: 'valid email address',
from: 'your verified email address', //e.g. single sender verification in SendGrid
cc: 'valid email address',
bcc: 'valid email address',
replyTo: 'valid email address',
subject: 'The Strapi Email feature worked successfully',
text: 'Hello world!',
html: 'Hello world!',
}),
Using the sendTemplatedEmail()
function
The sendTemplatedEmail()
function is used to compose emails from a template. The function compiles the email from the available properties and then sends the email.
To use the sendTemplatedEmail()
function, define the emailTemplate
object and add the function to a controller or service. The function calls the emailTemplate
object, and can optionally call the emailOptions
and data
objects:
Parameter | Description | Type | Default |
---|---|---|---|
emailOptions Optional | Contains email addressing properties: to , from , replyTo , cc , and bcc | object | |
emailTemplate | Contains email content properties: subject , text , and html using Lodash string templates | object | |
data Optional | Contains the data used to compile the templates | object |
The following code example can be used in a controller or a service:
const emailTemplate = {
subject: 'Welcome <%= user.firstname %>',
text: `Welcome to mywebsite.fr!
Your account is now linked with: <%= user.email %>.`,
html: `<h1>Welcome to mywebsite.fr!</h1>
<p>Your account is now linked with: <%= user.email %>.<p>`,
};
await strapi.plugins['email'].services.email.sendTemplatedEmail(
{
to: user.email,
// from: is not specified, the defaultFrom is used.
},
emailTemplate,
{
user: _.pick(user, ['username', 'email', 'firstname', 'lastname']),
}
);
Sending emails from a lifecycle hook
To trigger an email based on administrator actions in the admin panel use lifecycle hooks and the send()
function.
The following example illustrates how to send an email each time a new content entry is added in the Content Manager use the afterCreate
lifecycle hook:
- JavaScript
- TypeScript
module.exports = {
async afterCreate(event) { // Connected to "Save" button in admin panel
const { result } = event;
try{
await strapi.plugin('email').service('email').send({ // you could also do: await strapi.service('plugin:email.email').send({
to: 'valid email address',
from: 'your verified email address', // e.g. single sender verification in SendGrid
cc: 'valid email address',
bcc: 'valid email address',
replyTo: 'valid email address',
subject: 'The Strapi Email feature worked successfully',
text: '${fieldName}', // Replace with a valid field ID
html: 'Hello world!',
})
} catch(err) {
console.log(err);
}
}
}
export default {
async afterCreate(event) { // Connected to "Save" button in admin panel
const { result } = event;
try{
await strapi.plugins['email'].services.email.send({
to: 'valid email address',
from: 'your verified email address', // e.g. single sender verification in SendGrid
cc: 'valid email address',
bcc: 'valid email address',
replyTo: 'valid email address',
subject: 'The Strapi Email feature worked successfully',
text: '${fieldName}', // Replace with a valid field ID
html: 'Hello world!',
})
} catch(err) {
console.log(err);
}
}
}