=== Custom SMTP: Email Deliverability - FREE & Easy-to-use ===
Contributors: nicolasverlhiac
Tags: smtp, email, deliverability, mail logger, email logger
Requires at least: 6.0
Tested up to: 7.0
Stable tag: 2.7.3
Requires PHP: 7.4
License: GPLv2 or later

WordPress can't send email reliably on its own. Send through your SMTP provider, log every message, get alerts when sending breaks. Free, no upsell.

== Description ==

### Make your WordPress email arrive

WordPress still hands your email to the PHP mail() function. Most hosts have switched it off or throttled it because spammers loved it, and where it still runs, unauthenticated mail lands in spam. If your contact form says thank you and nothing ever arrives, this is why.

Custom SMTP sends your email through the provider you already use instead: your host's SMTP server, Gmail, Outlook, Brevo, SendGrid, Mailgun, Postmark or the Amazon SES API. It logs every message with its outcome, lets you preview and resend failures, and alerts you when sending spikes or starts failing. Everything is in the free plugin: no account to create, no third-party relay, no pro version.

Built for modern WordPress: **WordPress 7.0 ready**, **PHPMailer 7.0.2 compatible**, **stateless / cloud-ready** (Docker, Kubernetes), and **fully translated in English and French**.

Documentation lives at [customsmtp.com/docs/](https://customsmtp.com/docs/), with [step-by-step guides](https://customsmtp.com/guides/) for twelve providers and a [developer guide](https://customsmtp.com/developers/) covering constants, environment variables and the Amazon SES API.

### Send through your own SMTP provider

Point the plugin at the server you already pay for or the free tier you already use, with a preset that fills the technical values for you:

* **Presets for twelve providers**: Gmail, Outlook, Amazon SES, SendGrid, Mailgun, Brevo, Postmark, Mailjet, Zoho, Yahoo, iCloud and Scaleway, plus "Other / Custom" for any SMTP server.
* **From Name and From Email** applied to every outgoing email, with optional Reply-To, CC and BCC.
* **SSL/TLS encryption**, and optional authentication for relay servers that need none.
* **Password encrypted at rest** (AES-256-CBC with your WordPress salts), never displayed back in the form.
* **Test without guessing**: test the SMTP connection without sending anything, or send yourself a real test email.

### A log of every email, with preview and resend

Never wonder if your emails were sent again. Logging works out of the box and captures every message going through wp_mail(): WooCommerce order notifications, contact form submissions, password resets, all of it.

* Delivery status (sent or failed) with the exact SMTP error when a message fails, and the stored headers for advanced troubleshooting.
* **Preview the email body in wp-admin**, in an Outlook-style sidebar, without sending anything again; view the HTML source, or download any email as an HTML file for archiving.
* **Resend a failed email** straight from the logs once your configuration is fixed.
* Search by recipient, subject or status; filter by date range; export to CSV for reporting and compliance.
* Configurable retention with automatic purge (30 days by default), and content storage you can switch off in one click.

### Unusual Usage Alerts

A compromised contact form or a runaway plugin can turn your site into a spam relay, and a revoked password or an exhausted provider quota can stop your emails silently. Custom SMTP watches for both and warns you.

* **Sending spikes** — get an email when more messages than expected go out within an hour or a day. Thresholds are absolute, never relative, so a quiet site that sends a handful of emails a week is never woken up by statistical noise.
* **Delivery failures** — get warned as soon as several emails fail in a row, or when too many of the last messages sent failed. Counted over the last emails sent rather than over a period of time, so it works just as well on a site that sends twice a week as on a busy store.
* **A channel that survives the outage** — alerts go out by email, to an optional HTTPS webhook (Slack, Teams, any JSON endpoint), and to a persistent notice in wp-admin, because the one moment you need the alert is the moment email itself is broken.
* **No noise** — a configurable cooldown keeps an ongoing incident from filling your inbox, and the alert email is never logged nor counted against your own thresholds.
* **Off by default** — turn it on in Settings and set the thresholds that match your site.

### Manage WordPress Notifications

WordPress sends a handful of emails on its own, and some of them get old fast: a notice to the administrator every single time a user resets their password, a report after every automatic plugin update, a message for every comment awaiting moderation. Switch off the ones you do not want, one checkbox each, no code.

* **Password reset and new user notices to the administrator** — the user still gets their reset link and their welcome email, only the copy to the admin stops.
* **Automatic update reports** — core, plugins and themes, separately.
* **Comment notifications** — awaiting moderation, and new comment to the post author.
* **Nothing is hidden from you** — a notification you switch off is never created, so it will not appear in the Email Logs either, and the screen tells you that.
* **Account recovery is never at risk** — the emails users need to regain access to their account are deliberately out of reach of this screen.
* **Off means off, on stays on** — installing or updating the plugin never silences an email your site was already sending.

### Deliverability, privacy, security

* Cooperates with the automatic Envelope-From / Return-Path behavior introduced in WordPress 6.9, which improves SPF, DKIM and DMARC alignment on strict hosts (Amazon SES, Postmark, etc.).
* UTF-8 and emoji handled end-to-end in subjects, bodies and headers.
* All data stays in your WordPress database: no third-party calls, no telemetry, and no external processor to declare in your GDPR records.
* Email preview rendered in a sandboxed iframe, so no JavaScript from a logged email ever runs in wp-admin.
* All admin actions protected with nonces and capability checks; the SMTP password is encrypted at rest.

### For developers: containers, config-as-code, Amazon SES API

The [developer guide](https://customsmtp.com/developers/) covers this surface in depth; the short version:

* **Stateless and cloud-ready**: no filesystem writes, no shared storage, safe on read-only filesystems. Works on Docker, Kubernetes, AWS ECS/Fargate, Google Cloud Run, and with Bedrock or Trellis stacks.
* **Every setting from a constant or environment variable**: define `CUSTOM_SMTP_<SETTING>` and it overrides the saved value everywhere, with the field shown read-only in wp-admin and a badge naming the variable. On Multisite, a network-wide option can configure every site at once.
* **Amazon SES API with IAM roles**: send through the SESv2 API authenticated by your ECS task role or EC2 instance role, with no access keys and no stored credentials. Raw MIME preserves HTML, attachments, CC/BCC, Reply-To and custom headers, and it works with or without the AWS SDK for PHP. Details in the FAQ below.
* **Abilities API (WordPress 6.9+)**: `custom-smtp/connection-health` and `custom-smtp/send-test-email` are exposed to MCP-enabled AI assistants and automation tools (n8n, Make), behind the same `manage_options` capability check as wp-admin.

== Screenshots ==

1. Email Logs - every email is logged with its delivery status, and failed sends show the exact SMTP error. Search, filter by status or date, and export to CSV.
2. SMTP Settings - pick a provider preset (Gmail, Brevo, SendGrid and more), fill in your credentials and you are done. The status bar confirms email delivery is active.
3. Email Preview - click any logged email to read its full content in an Outlook-style sidebar, without sending anything again.
4. Unusual Usage Alerts - get warned by email, webhook or admin notice when sending spikes or delivery failures pile up. Every threshold is yours to tune.
5. Test tools - check your configuration in one click: test the SMTP connection or send yourself a real test email.

== Installation ==

1. Install Custom SMTP either via the WordPress.org plugin repository or by uploading the files to your server.
2. Navigate to Settings > Custom SMTP in the WordPress admin.
3. Select a provider preset (Gmail, Outlook, AWS SES, SendGrid, Mailgun, Brevo, Postmark, Mailjet, Zoho, Yahoo, iCloud, Scaleway) or pick "Other / Custom" and enter your SMTP details manually.

1, 2, 3: You're done!

On AWS (ECS/Fargate, EC2)? Choose the **Amazon SES (API · IAM role)** mailer instead of SMTP to send with no stored credentials — see the SES question in the FAQ.

== Frequently Asked Questions ==

= Where do I find the documentation? =

On [customsmtp.com/docs/](https://customsmtp.com/docs/), which covers every screen and setting of the plugin. Each provider preset also has its own [step-by-step guide](https://customsmtp.com/guides/), with the exact values the preset fills in. The [developer guide](https://customsmtp.com/developers/) goes further: forcing any setting from a PHP constant or an environment variable, running on immutable or containerized WordPress, and sending through the Amazon SES API with an IAM role.

For anything not covered there, the support forum on this page is the right place to ask.

= What SMTP settings should I use? =

Custom SMTP includes presets for popular providers (Gmail, Outlook, AWS SES, SendGrid, etc.). Just select your provider and settings are auto-filled.

= List of SMTP Servers =

Here's a reference list of common SMTP servers:

**Professional Email Services**
* SendGrid: smtp.sendgrid.net – TLS – Port 587
* Mailgun: smtp.mailgun.org – TLS – Port 587
* Amazon SES: email-smtp.[region].amazonaws.com – TLS – Port 587
* Brevo (Sendinblue): smtp-relay.brevo.com – TLS – Port 587
* Postmark: smtp.postmarkapp.com – TLS – Port 587
* Mailjet: in-v3.mailjet.com – TLS – Port 587
* Scaleway: smtp.tem.scaleway.com - TLS - Port 587

**Consumer Email Providers**
* Gmail: smtp.gmail.com – TLS – Port 587
* Outlook/Office365: smtp.office365.com – TLS – Port 587
* Yahoo Mail: smtp.mail.yahoo.com – TLS – Port 587
* iCloud: smtp.mail.me.com – TLS – Port 587
* Zoho: smtp.zoho.com – TLS – Port 587
* AOL: smtp.aol.com – TLS – Port 587
* GMX: smtp.gmx.com – SSL – Port 465

**ISP Email (Regional)**
* Comcast: smtp.comcast.net – Port 587
* Verizon: outgoing.verizon.net – SSL – Port 465
* AT&T: smtp.mail.att.net – SSL – Port 465
* Orange: smtp.orange.net – Port 25
* T-Online: securesmtp.t-online.de – TLS – Port 587
* 1&1 IONOS: smtp.1and1.com – TLS – Port 587

Note: Settings may vary. Contact your provider for exact configuration.

= Does it work with WooCommerce? =

Yes! Custom SMTP logs all emails sent from WordPress, including WooCommerce order confirmations, shipping notifications, and customer emails.

= Is it compatible with contact form plugins? =

Yes, it works with Contact Form 7, WPForms, Gravity Forms, and any plugin that uses WordPress wp_mail() function.

= Is it compatible with stateless/containerized WordPress? =

Yes. Custom SMTP is fully stateless-compatible and works on ephemeral infrastructure (Docker, Kubernetes, AWS ECS/Fargate, Google Cloud Run, etc.) without shared storage like EFS or NFS.

The plugin stores all data in the WordPress database:

* Settings in `wp_options`
* Email logs in a custom database table
* CSV exports streamed directly to the browser (no temp files)
* Log purge scheduled via WP-Cron (database-backed)

It also works with modern WordPress stacks like Bedrock and Trellis, and can run on a read-only filesystem.

**Notes for stateless deployments:**

* Ensure WordPress salts (`LOGGED_IN_KEY`, `LOGGED_IN_SALT`) are consistent across all instances — the SMTP password encryption depends on them.
* If `DISABLE_WP_CRON` is set to `true`, configure an external cron to trigger `wp-cron.php` so automatic log purge runs properly.
* On AWS, prefer the **Amazon SES (API)** mailer with an IAM role (see the SES question below) — it removes the need to store any SMTP credentials at all.

= Can I send through Amazon SES without storing any credentials? =

Yes. Custom SMTP includes an **Amazon SES (API)** mailer that authenticates through your AWS **IAM role** (the ECS task role or EC2 instance role) using the AWS default credential chain. You never enter or store an access key, secret key, or SMTP credential — ideal for stateless, containerized WordPress on AWS ECS/Fargate.

In Settings > Custom SMTP, choose "Amazon SES (API · IAM role)" as the mailer, set the region and a verified sender address (or inject them as environment variables), and you're done. You can also provide a SES Configuration Set for bounce/complaint tracking, and "Send Test Email" returns the SES MessageId so you can confirm the send on the AWS side.

The following environment variables / PHP constants take priority over the saved settings, so the same container image works across environments:

* `SES_REGION` (falls back to `AWS_REGION`) — e.g. `eu-west-3`
* `SES_FROM_EMAIL` — the verified sender address
* `SES_CONFIG_SET` — optional SES configuration set

The message is sent as raw MIME, so HTML, attachments, CC/BCC, Reply-To and custom headers are all preserved. The mailer works whether or not the AWS SDK for PHP is installed (it falls back to a built-in signed API client), and SES sends are logged in the Email Logs like any other email.

This is different from the existing **Amazon SES** SMTP preset, which uses SMTP credentials — the new mailer uses the SES API and your IAM role instead.

= Can I configure everything from environment variables (config-as-code)? =

Yes. Every setting can be forced from a PHP constant or environment variable, which takes priority over the value saved in the database — ideal for immutable Docker images and `DISALLOW_FILE_MODS` deployments.

Use `CUSTOM_SMTP_<SETTING>` in uppercase, for example:

* `CUSTOM_SMTP_MAILER_TYPE` — `smtp` or `ses_api`
* `CUSTOM_SMTP_HOST`, `CUSTOM_SMTP_PORT`, `CUSTOM_SMTP_SECURE`, `CUSTOM_SMTP_USERNAME`, `CUSTOM_SMTP_PASSWORD`
* `CUSTOM_SMTP_MAILFROM`, `CUSTOM_SMTP_FROMNAME`, `CUSTOM_SMTP_LOG_RETENTION`
* `CUSTOM_SMTP_ALERTS_ENABLED`, `CUSTOM_SMTP_ALERT_EMAIL`, `CUSTOM_SMTP_ALERT_WEBHOOK`, `CUSTOM_SMTP_ALERT_MAX_PER_HOUR`, `CUSTOM_SMTP_ALERT_MAX_PER_DAY`, `CUSTOM_SMTP_ALERT_COOLDOWN`

The Amazon SES shortcuts also apply: `SES_REGION` (or `AWS_REGION`), `SES_FROM_EMAIL`, `SES_CONFIG_SET`.

An empty value counts as "not set", so it never overrides anything. To force a boolean setting off, give it an explicit value: `CUSTOM_SMTP_ALERTS_ENABLED=false` (or `0`), not an empty string.

To switch an entire Multisite network to Amazon SES with no database changes, set in your container: `CUSTOM_SMTP_MAILER_TYPE=ses_api`, `SES_REGION=eu-west-3`, `SES_FROM_EMAIL=no-reply@example.com`.

Values are resolved from PHP constants, then `getenv()`, `$_ENV`, and `$_SERVER`. The `$_SERVER` source means FrankenPHP (including worker mode) and Bedrock-style stacks work with plain environment variables — no constants required.

On Multisite, the plugin also reads a network-wide option (via `get_site_option`) beneath any per-site option, so a single configuration can apply to all sites. Fields supplied by the environment are shown read-only in the settings page with a badge naming the source variable. (A password supplied via `CUSTOM_SMTP_PASSWORD` is used as-is; only stored passwords are encrypted at rest.)

= Can AI assistants or automation tools manage my SMTP? =

Yes, on WordPress 6.9+. Custom SMTP registers two abilities with the WordPress Abilities API:

* `custom-smtp/connection-health` returns the current SMTP state (configured, host, port, encryption, auth, logging retention) — useful for diagnostics and monitoring.
* `custom-smtp/send-test-email` triggers a test email through the configured SMTP server.

Both abilities are accessible to MCP-compatible AI clients, automation workflows (n8n, Make), and other plugins. They enforce the same capability check as the wp-admin interface (`manage_options`), so unprivileged users or scripts cannot invoke them.

== Changelog ==

= 2.7.3 =
*Dead v1.x files removed from the package, translations unblocked*

* Removed the `includes/` directory inherited from version 1.x. Those files stopped being loaded in 2.5 but were still shipped in the download. Nothing changes in how the plugin works, the package is simply lighter and free of dead code.
* Translators can now finish their work. The plugin exposed 281 translatable strings, of which 51 came from those leftover files and appeared nowhere in the interface. Translating the entire visible plugin capped out at 82%, below the 90% WordPress.org requires to build an official language pack. The project is now down to its 230 real strings, so the threshold is reachable: [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/custom-smtp/)

= 2.7.2 =
*Scaleway provider preset, refreshed listing*

* New provider preset: **Scaleway** (Transactional Email). Selecting it fills the SMTP relay (`smtp.tem.scaleway.com`, port 587, TLS); the [step-by-step guide](https://customsmtp.com/guides/scaleway/) covers the unusual credentials (the username is your Project ID, the password is the secret key of an API key) and the domain validation Scaleway requires before the first email.
* Reorganized this plugin page: the description now follows the reader's need (provider, email log with preview and resend, alerts, WordPress notification switches) with a single developers block at the end; the deep Amazon SES and config-as-code material stays in the FAQ.
* First banners on the listing, in English and French, matching the site's design.

= 2.7.1 =
*Documentation links*

* The Documentation links in wp-admin now point to the documentation hub at [customsmtp.com/docs/](https://customsmtp.com/docs/), and each provider preset links to its own step-by-step guide on customsmtp.com (Gmail, Outlook, Amazon SES, SendGrid, Mailgun, Brevo, Postmark, Mailjet, Zoho, Yahoo, iCloud) instead of the provider's generic documentation. Each guide carries the exact values the preset fills in and still links to the official provider documentation.
* Completed the French translation: the settings screen, the email logs screen and the test/error messages introduced in 2.x are now fully translated, and the encryption level "None" is now translatable.

= 2.7.0 =
*Manage WordPress notifications*

* New **WordPress Notifications** section in the settings: switch off the emails WordPress sends on its own, one by one, with no code.
* Covers the password reset notice to the administrator, the new user notice to the administrator, the reports from automatic core, plugin and theme updates, the comment awaiting moderation notice, and the new comment notice to the post author.
* A notification you switch off is never created, so it does not appear in the Email Logs either. The screen says so, to avoid hunting for an email you turned off yourself.
* Emails your users need to keep control of their account, such as the password reset link itself or the address change confirmation, are deliberately out of reach: a settings screen should never be able to break account recovery.
* Nothing is switched off by default, so installing or updating the plugin never silences an email your site was already sending.
* Each switch is a normal setting, so it can be forced from a PHP constant or environment variable like everything else (`CUSTOM_SMTP_NOTIFY_ADMIN_PASSWORD_RESET` and friends).
* Thanks to @aleksandreeu on the support forum for asking for this.

= 2.6.1 =
*Fixes*

* **Fixed: the SMTP password was stored double-encrypted on the first save.** On a site where the settings had never been saved before, WordPress ran the validation callback twice and the password was encrypted a second time, so authentication failed and "Test Connection" reported an error until the settings were saved again. Existing sites are unaffected; if you hit this, saving your password once more is enough.
* **Fixed: concurrent alert checks could send the same alert several times.** The lock guarding the periodic check was not atomic, so on a busy site several processes could run it at once and each send its own email. It now relies on a single atomic insert, and the inline failure rule is guarded the same way.
* Added two QA scripts under `bin/` (not shipped in the plugin) that replay the alert and settings scenarios against a wp-env site with real assertions.

= 2.6.0 =
*Unusual usage alerts*

* New **Unusual Usage Alerts** section in the settings: get warned when email activity looks abnormal, either a sending spike (compromised form, runaway plugin) or a delivery breakdown (revoked credentials, exhausted quota, relay down).
* **Volume rules** — alert above a configurable number of emails per hour and per day. Thresholds are absolute rather than relative, so a low traffic site is never alerted for what is only statistical noise.
* **Failure rules** — alert on consecutive failures (detected immediately, without waiting for cron, and even when logging is disabled) and on too many failures among the last emails sent. Counting over the last sends rather than over a time window keeps the check meaningful on sites that send a couple of emails a week.
* **Three delivery channels** — email to the address of your choice (the site administrator by default), an optional HTTPS webhook for Slack, Teams or any JSON endpoint, and a persistent wp-admin notice. The webhook and the notice still work when email delivery itself is the problem.
* **Cooldown** — a configurable delay before the same alert can fire again, so an ongoing incident does not fill your inbox.
* The alert email is excluded from the logs and from its own thresholds, via the new `custom_smtp_skip_log` filter.
* Every alert setting can be forced from a PHP constant or environment variable like the rest of the configuration (`CUSTOM_SMTP_ALERTS_ENABLED`, `CUSTOM_SMTP_ALERT_MAX_PER_HOUR`, `CUSTOM_SMTP_ALERT_WEBHOOK`, and so on).
* Alerts are **off by default**: enable them and adjust the thresholds to your own traffic.

= 2.5.0 =
*Resend failed emails from the logs*

* New **Resend** action on failed entries in the Email Logs: re-send a message that didn't go through (e.g. after fixing your SMTP/SES configuration) directly from wp-admin, without having to trigger the original action again.
* The resend goes through your currently configured mailer (SMTP or Amazon SES) and is captured as a new log entry.
* Recipient, subject, body and headers are reconstructed from the stored log. The Resend action appears only on failed entries whose body was stored — enabling **Store email content** is what makes a failed email replayable. Attachments are not stored, so they are not included (the confirmation dialog notes this when the entry had attachments).

= 2.4.1 =
*Environment compatibility*

* Constant / environment overrides are now also read from `$_SERVER`, where FrankenPHP (worker mode, where `getenv()` is unreliable) and Bedrock-style setups expose environment variables reliably — enabling 100% env-var configuration on those stacks without declaring PHP constants. Resolution order: constant → `getenv()` → `$_ENV` → `$_SERVER`. Only the plugin's fixed variable names are read, and client request headers (which land in `$_SERVER` as `HTTP_*` keys) cannot spoof them.

= 2.4.0 =
*Config-as-code: constant/env overrides for every setting + Multisite network settings*

**Config-as-code**
* Every setting can now be forced from a PHP constant or environment variable, taking priority over the database value — built for immutable images and `DISALLOW_FILE_MODS`. Use `CUSTOM_SMTP_<SETTING>` (e.g. `CUSTOM_SMTP_MAILER_TYPE`, `CUSTOM_SMTP_HOST`, `CUSTOM_SMTP_LOG_RETENTION`).
* The mailer selection (`mailer_type`) is now overridable — set `CUSTOM_SMTP_MAILER_TYPE=ses_api` to activate Amazon SES across a whole site or network with no per-site configuration and no custom `option_*` filter.
* The existing Amazon SES shortcuts (`SES_REGION` / `AWS_REGION`, `SES_FROM_EMAIL`, `SES_CONFIG_SET`) continue to work and now sit in the same unified override system.
* Settings supplied by the environment are shown read-only in wp-admin with a "from `VARIABLE`" badge so the source is visible.

**Multisite**
* On a network, settings are read from the network-wide option (`get_site_option`) beneath any per-site option, so one configuration can apply to all sites.

**Note**
* SMTP passwords supplied via `CUSTOM_SMTP_PASSWORD` are used as-is (not decrypted) — only stored passwords are encrypted at rest.

= 2.3.0 =
*New mailer: Amazon SES API with IAM role authentication*

**New Feature — Amazon SES (API) mailer**
* New mailer type that sends through the Amazon SESv2 API instead of SMTP, authenticated **exclusively** by the server's AWS IAM role (ECS task role / EC2 instance role) via the AWS default credential chain — **no access keys, secret keys, or SMTP credentials** are stored or required.
* Built for stateless, containerized WordPress on AWS (ECS/Fargate): no secrets in the database, following 12-factor principles.
* Full message fidelity — HTML, attachments, CC/BCC, Reply-To and custom headers are preserved (sent as raw MIME); BCC recipients are delivered via the SES envelope and stay hidden.
* Optional **SES Configuration Set** support for bounce/complaint tracking and CloudWatch metrics.
* Region, sender address and configuration set can be injected via environment variables / constants (`SES_REGION` / `AWS_REGION`, `SES_FROM_EMAIL`, `SES_CONFIG_SET`), overriding the stored settings — so the same image runs across environments.
* Dependency-free — uses the AWS SDK for PHP when present, otherwise a built-in SigV4-signed API client over the WordPress HTTP API (nothing to bundle).
* "Send Test Email" returns the SES MessageId on success.
* SES sends are captured by the Email Logs (status, content preview) just like SMTP sends.
* Note: this is distinct from the existing **Amazon SES** SMTP preset, which uses SMTP credentials. The new mailer uses the SES API and IAM roles.

= 2.2.1 =
*Documentation update*

* Surfaced the Abilities API integration (shipped in 2.2.0) in the plugin description and FAQ — users can now discover the AI / workflow capabilities directly from the WordPress.org plugin page without digging into the changelog.
* Added dedicated **Deliverability** section highlighting SPF/DKIM alignment, PHPMailer 7.0.2 compatibility, and UTF-8/emoji handling.
* Added dedicated **Privacy & GDPR-friendly** section listing the existing privacy mitigations (encryption at rest, automatic log purge, opt-out content storage, sandboxed preview).
* Mentioned the English / French translations and the "built for modern WordPress" stance in the intro.
* Fixed the Installation steps: removed an incorrect "by WPForms" mention and refreshed the provider preset list to match the 11 presets actually shipped (Gmail, Outlook, AWS SES, SendGrid, Mailgun, Brevo, Postmark, Mailjet, Zoho, Yahoo, iCloud).
* Refreshed the WordPress.org tags (`smtp, email, deliverability, mail logger, email logger`) to better reflect the plugin's positioning.
* No functional changes.

= 2.2.0 =
*WordPress 7 compatibility release*

**WordPress 7 Compatibility**
* Verified compatibility with WordPress 7.0 and PHPMailer 7.0.2 (no code changes required — plugin uses only public PHPMailer properties and methods).
* Cooperates with the automatic Envelope-From / Return-Path behavior introduced in WordPress 6.9, so SPF/DKIM alignment now works correctly on strict hosts without manual configuration.
* Added a contextual note under the From Email field explaining the new envelope sender behavior on WordPress 6.9+.

**New Integration**
* Abilities API support (WordPress 6.9+): two server-side abilities are now exposed for AI assistants, dashboards, and workflow tools.
  * `custom-smtp/connection-health` — returns whether SMTP is configured, host, port, encryption mode, auth state, and log retention.
  * `custom-smtp/send-test-email` — sends a test email through the configured SMTP server.

**Changed Defaults**
* **Store Email Content** is now enabled by default on new installs so the log preview is useful out of the box. Existing installs keep their saved preference. You can still disable it from the Email Logging settings card; with the default log retention of 30 days, stored bodies are automatically purged.

**Also Included (from the 2.1.0 line)**
* iCloud Mail provider preset.
* Documented stateless and cloud-ready compatibility (Docker, Kubernetes, ECS/Fargate, Cloud Run, Bedrock, Trellis).
* Removed legacy v1.x procedural code; the v2.x OOP architecture is now the single source of truth.

= 2.1.0 =
*Release Date - May 26, 2026*

**New Features**
* Provider Presets: One-click configuration for Gmail, Outlook, AWS SES, SendGrid, Mailgun, Brevo, Postmark, Mailjet, Zoho, Yahoo, and iCloud.
* Auto-fill settings: Select a provider and Host, Port, Encryption, Authentication are automatically configured.
* Documentation links: Quick access to each provider's SMTP documentation.

**UI Improvements**
* Redesigned settings page with card-based layout.
* Status bar showing SMTP configuration state at a glance.
* Collapsible Advanced Settings section.
* Save button in each settings card for quick access.
* Responsive design for mobile admin access.

**Documentation**
* Documented stateless and cloud-ready compatibility (Docker, Kubernetes, ECS/Fargate, Cloud Run, Bedrock, Trellis).
* Expanded FAQ with the full list of supported SMTP providers.

**Maintenance**
* Removed legacy v1.x procedural code; the v2.x OOP architecture is now the single source of truth.

= 2.0.0 =
*Release Date - February 4, 2026*

**Major Release - Architecture Refactor & Email Logging**

**New Features**
* Email Logging: Track all sent emails with recipient, subject, date/time, and status (success/failed).
* Email Logs Dashboard: View all logged emails with search, filters, and pagination.
* Email Preview Sidebar: View full email content in an Outlook-style sidebar panel.
* Email Content Storage: Optionally store complete email body for later preview (disabled by default for privacy).
* Download Email: Export any logged email as HTML file for archiving or debugging.
* Date Range Filters: Quick filters for Today, Last 7 days, Last 30 days.
* CSV Export: Export email logs to CSV for reporting and analysis.
* Auto-purge: Configurable log retention (default 30 days) with automatic cleanup.
* Statistics Bar: Compact inline stats showing total, sent, failed, and today's email counts.
* Refresh Button: One-click refresh of email logs.

**Architecture**
* Complete OOP refactor with PSR-4 namespaces (CustomSMTP\\).
* Dependency injection pattern for better testability.
* Separated concerns: Plugin, Settings, Mailer, Logger, Encryption classes.
* Custom database table for email logs.

**Security**
* Email preview uses sandboxed iframe (no JavaScript execution).
* Email body limited to 500KB to prevent database bloat.
* All AJAX actions protected with nonce verification and capability checks.

**Improved**
* Cleaner, more maintainable codebase.
* Better separation of admin UI and core functionality.
* Enhanced error handling throughout.
* Responsive design for mobile admin access.

**Note**
* All v1.x settings are preserved and compatible.
* Email logging is enabled by default (can be disabled in settings).
* Email content storage is disabled by default - enable in settings to use preview feature.

= 1.9.0 =
*Release Date - December 5, 2025*

**Security**
* SMTP password is now encrypted in the database using AES-256-CBC with WordPress salts.
* Password field no longer displays the stored value (shows placeholder instead).

**Added**
* New "Test Connection" button to verify SMTP settings without sending an email.
* New "SMTP Authentication" option (Yes/No) to support relay servers without authentication.
* Improved error messages: common PHPMailer errors are now translated to user-friendly messages.

**Changed**
* Test buttons now show "Test Connection" and "Send Test Email" separately.
* Password field shows "Leave empty to keep current password" when a password is already saved.

**Note**
* Existing plaintext passwords will continue to work and will be encrypted on next save.

= 1.8.1 =
*Release Date - December 5, 2025*

**Fixed**
* WordPress 6.9 compatibility: Use `wp_mail_from` filter instead of setting From in `phpmailer_init` (fixes "Invalid address" error).
* Fixed test email button not working due to duplicate PHPMailer hooks.

**Changed**
* **Breaking:** "Mail From" field moved from Optional to Main settings (now required for WordPress 6.9+).
* Test button now auto-saves settings before sending test email.
* Improved error messages: shows which required fields are missing.
* Disabled SMTPAutoTLS when security is set to "None" (fixes Mailpit/local testing).

= 1.8.0 =
*Release Date - December 4, 2025*

**Fixed**
* WordPress 6.9 compatibility: Fixed email sending failure with AWS SES and other SMTP providers that require verified sender addresses.
* Added proper Envelope-From (Sender/Return-Path) configuration to comply with WordPress 6.9 PHPMailer changes.
* Test emails now correctly use the configured "Mail From" address as the envelope sender.

**Changed**
* Minimum WordPress version updated to 6.0.
* Minimum PHP version updated to 7.4.

**Note**
* Users must configure the "Mail From" field in optional settings with a verified email address (especially important for AWS SES users).

= 1.7 =
*Release Date - July 5, 2024*

**Improved**
* Improved security of saved options with appropriate validation and sanitization.
* Code optimization by removing unused code comments and adding value checks before use.
* Split the main custom-smtp.php file into several files to improve maintainability and readability.
* Creation of includes/admin, includes/smtp and includes/utils folders to organize code by functionality.

**Fixed**
* Fixed validation of `secure` options to ensure they are either `none`, `ssl` or `tls`.
* Translations : Test email.

= 1.6 =
*Release Date - April 3, 2024*

* New optional settings for all emails sent by WordPress:
    * Addition of "Reply To" option: This feature allows you to specify an email address that recipients will send replies to, instead of the original sender's email address. This is useful when the sender does not wish to receive replies directly.
    * Addition of "CC" option: "CC" stands for "Carbon Copy". When you CC an email to someone, you send them a copy of your email. The CC'd person may not be the main recipient of the email, but they are included for their reference. Everyone who receives the email can see who has been CC'd.
    * Addition of "BCC" option: "BCC" stands for "Blind Carbon Copy". This works like CC, but BCC recipients are hidden from the other recipients. This is useful when you want to inform someone without letting others know that they are also receiving the same email.
* Incompatible plugin detection: This feature helps identify any plugins that are not compatible and could potentially cause issues (proactive approach to prevent conflicts). It will alert you if an installed plugin is not compatible with the Custom SMTP plugin, allowing you to take necessary action.
* Comprehensive test email with configuration information

= 1.5 =
*Release Date - March 14, 2024*

* You can test your SMTP settings before saving them.
* Secure SMTP option accept `None` as value.
* Custom CSS for Settings.

= 1.4 =
*Release Date - March 12, 2024*

* Public launch of the plugin!
* Completely translated into English and French.
* All SMTP options are editable.
