# Advanced Nodemailer configuration

> Source: https://docs.strapi.io/cms/configurations/email-nodemailer

The Nodemailer provider supports OAuth2 authentication, connection pooling, DKIM signing, and rate limiting. Each scenario adds specific keys to `providerOptions` on top of a standard SMTP configuration.

This page covers production scenarios for the community `@strapi/provider-email-nodemailer` package that can be used with the [Email feature](/cms/features/email). For basic provider installation and SMTP setup, see [Configuring providers](/cms/features/email#configuring-providers).

:::info Supported providers
For the full list of supported `providerOptions`, refer to the [provider README on npm](https://www.npmjs.com/package/@strapi/provider-email-nodemailer).
:::

## OAuth2 authentication

For services like Gmail or Outlook that require OAuth2 instead of a password:

```js title="/config/plugins.js"
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        // highlight-start
        auth: {
          type: 'OAuth2',
          user: env('SMTP_USER'),
          clientId: env('OAUTH_CLIENT_ID'),
          clientSecret: env('OAUTH_CLIENT_SECRET'),
          refreshToken: env('OAUTH_REFRESH_TOKEN'),
        },
        // highlight-end
      },
      settings: {
        defaultFrom: env('SMTP_USER'),
        defaultReplyTo: env('SMTP_USER'),
      },
    },
  },
});
```
```ts title="/config/plugins.ts"

  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        // highlight-start
        auth: {
          type: 'OAuth2',
          user: env('SMTP_USER'),
          clientId: env('OAUTH_CLIENT_ID'),
          clientSecret: env('OAUTH_CLIENT_SECRET'),
          refreshToken: env('OAUTH_REFRESH_TOKEN'),
        },
        // highlight-end
      },
      settings: {
        defaultFrom: env('SMTP_USER'),
        defaultReplyTo: env('SMTP_USER'),
      },
    },
  },
});
```

## Connection pooling

Use connection pooling to reuse SMTP connections and improve throughput when sending many emails:

```js title="/config/plugins.js"
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 465,
        secure: true,
        // highlight-start
        pool: true,
        maxConnections: 5,
        maxMessages: 100,
        // highlight-end
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```
```ts title="/config/plugins.ts"

  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 465,
        secure: true,
        // highlight-start
        pool: true,
        maxConnections: 5,
        maxMessages: 100,
        // highlight-end
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```

## DKIM signing

Add DKIM signatures to improve deliverability and authenticate outbound mail:

```js title="/config/plugins.js"
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 587,
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
        // highlight-start
        dkim: {
          domainName: 'example.com',
          keySelector: 'mail',
          privateKey: env('DKIM_PRIVATE_KEY'),
        },
        // highlight-end
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```
```ts title="/config/plugins.ts"

  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 587,
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
        // highlight-start
        dkim: {
          domainName: 'example.com',
          keySelector: 'mail',
          privateKey: env('DKIM_PRIVATE_KEY'),
        },
        // highlight-end
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```

## Rate limiting

Limit the number of messages sent per time interval to avoid triggering spam filters:

```js title="/config/plugins.js"
module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 465,
        secure: true,
        pool: true,
        // highlight-start
        rateLimit: 5,    // max messages per rateDelta
        rateDelta: 1000, // time interval in ms (1 second)
        // highlight-end
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```
```ts title="/config/plugins.ts"

  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 465,
        secure: true,
        pool: true,
        // highlight-start
        rateLimit: 5,
        rateDelta: 1000,
        // highlight-end
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'hello@example.com',
        defaultReplyTo: 'hello@example.com',
      },
    },
  },
});
```

:::note Rate limiting requires connection pooling
`rateLimit` and `rateDelta` only take effect when `pool: true` is also set.
:::
