You don’t need a plugin to send WordPress email over SMTP. Define SMTP creds in ‘wp-config.php’ and hook ‘phpmailer_init’ in your theme (or a small “must-use” mu-plugin) to configure ‘PHPMailer’. Test with ‘wp_mail()’ or ‘WP-CLI’.
Table of contents
Open Table of contents
Why do this?
- Reliability: Many hosts block mail() or throttle it. SMTP via your transactional provider (Postmark, SendGrid, Mailgun, SES, etc.) is far more deliverable.
- Security & control: Keep credentials outside the DB, version your code, and avoid plugin bloat.
- Portability: Same approach works on shared hosts, VPS, and containers.
Assumptions: You’re comfortable editing theme files / mu-plugins and have SMTP credentials from a provider. Tested on modern WordPress 6.x.
Step 1 – Put SMTP secrets in wp-config.php
Add constants so code doesn’t hardcode secrets.
// ==========================================
// SMTP Configuration for wp_mail
// ==========================================
define('SMTP_HOST', 'smtp.example.com');
define('SMTP_PORT', 587); // 587 (TLS/STARTTLS) or 465 (SSL)
define('SMTP_USER', 'no-reply@example.com');
define('SMTP_PASS', 'your-super-secure-app-password');
define('SMTP_SECURE', 'tlsonly'); // 'tlsonly', 'ssl', or ''
define('SMTP_AUTH', true);
define('SMTP_FROM', 'no-reply@example.com');
define('SMTP_FROM_NAME', 'From The Green Code'); // Dedicated name constant
define('SMTP_DEBUG', false); // Change to true only when troubleshooting
wp-config.php
Step 2 – Configure PHPMailer via phpmailer_init
Add this to your theme’s functions.php, a small site-specific plugin, or better a file in wp-content/mu-plugins/ (loads on every request, independent of theme).
/*
**Catch wp_mail and route it through the SMTP constants defined in wp-config.php
*/
<?php
add_action('phpmailer_init', 'custom_smtp_mailer');
function custom_smtp_mailer($phpmailer) {
// Check if the required constants are defined before running
if (!defined('SMTP_HOST') || !defined('SMTP_USER') || !defined('SMTP_PASS')) {
return;
}
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->SMTPAuth = defined('SMTP_AUTH') ? SMTP_AUTH : true;
$phpmailer->Port = defined('SMTP_PORT') ? SMTP_PORT : 587;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
$phpmailer->SMTPSecure = defined('SMTP_SECURE') ? SMTP_SECURE : 'tlsonly';
// Set the From Email and Name
if (defined('SMTP_FROM')) {
$phpmailer->From = SMTP_FROM;
}
if (defined('SMTP_FROM_NAME')) {
$phpmailer->FromName = SMTP_FROM_NAME;
}
// Enable debugging if turned on in wp-config.php
if (defined('SMTP_DEBUG') && SMTP_DEBUG === true) {
$phpmailer->SMTPDebug = 2; // Output raw SMTP logs
}
}functions.php
That’s it. Every wp_mail() call now uses your SMTP server.
Step 3 – Test it
Create a temporary admin-only route or use a throwaway snippet:
wp_mail(
get_option('admin_email'),
'SMTP test from ' . get_bloginfo('name'),
"If you're reading this, SMTP is configured.\n\nTime: " . wp_date('c')
);
wp-mail.php
WP-CLI (preferred)
# From your WP root
wp eval "var_dump( wp_mail( 'you@example.com', 'SMTP test', 'Hello from WP-CLI' ) );"
root
If it returns bool(true) and you receive the email, you’re good.
Common provider examples
Replace host, ports, and security according to your provider’s docs.
SendGrid / Mailgun / Postmark (SMTP):
- Host: provided by vendor (e.g., smtp.sendgrid.net)
- Port: 587 (TLS) or 465 (SSL)
- Secure: tls or ssl
- Auth: true
- Username/Password: API key pattern per vendor
Amazon SES (SMTP):
- Host: email-smtp.
.amazonaws.com - Port: 587 (TLS) or 465 (SSL)
- Username/Password: SES SMTP credentials (generated in console)
Gmail / Google Workspace (less ideal for production):
- Host: smtp.gmail.com
- Port: 587 (TLS)
- Use an App Password (2FA required), not your account password.
FAQ
Does this survive theme changes?
Yes – if you place it in mu-plugins. If you put the hook in a theme’s functions.php, it depends on that theme.
Will core updates overwrite this?
No, your wp-config.php and mu-plugins/ are untouched by core updates.
Can I send different “From” per site on multisite?
Yes – set per-site constants (domain-specific wp-config.php).
If you’d like us to wire this up across environments (dev/stage/prod), integrate with your provider, and add basic delivery checks, we can help. We build scalable, reliable WordPress and Laravel systems with lean ops.