How to set up WordPress SMTP without a plugin

Illustration man at sorting machine

Pros and cons of WordPress email without a plugin

Avoiding yet another plugin to configure WordPress to send emails through a server or email service requires a little technical understanding, but provides several advantages:

  • Less clutter on your plugin management page
  • Sensitive SMTP credentials are stored in a safe location – the wp-config.php file
  • It just feels elegant

Of course, there are certain advantages to using an SMTP mailer plugin. For example a well-designed plugin might offer useful features such as log retention, being able to use a backup mail server, or being able to connect to some mail services’ APIs instead of SMTP ports. If those are the kind of features you might need, check out our roundup of WordPress mailer plugins.

Steps

1. Look up your SMTP provider’s settings and your credentials

Look up your email provider’s settings and your credentials. This information is typically provided by your email provider or hosting company. You will need to know the hostname of the mail server, the port number, and the type of encryption to use. You will also need your SMTP username and password for authentication.

For example, Microsoft provide their Outlook SMTP connection values, which look like this (see the “SMTP Settings” column):

Have a WordPress email problem right now? Ask us about it.

We’ll attempt to publish a solution ASAP for free. Challenge us!

So we can notify you when we publish a solution

Microsoft Outlook SMTP settings
Microsoft Outlook SMTP settings

2. Create and store two code snippets

There are two places into which you will need to place new code:

2.1 Wherever you store custom PHP code

Add the script below to wherever you normally embed code snippets. If you’re not sure where this is, see our article about ways to add custom code to WordPress. (Our favorite way of managing code snippets when we want to set up quick functionality without a plugin is by using the Code Snippets plugin.)

// Use wp-config.php constants in code snippet
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
  $phpmailer->isSMTP();
  $phpmailer->Host =       SMTP_HOST;
  $phpmailer->Username =   SMTP_USER;
  $phpmailer->Password =   SMTP_PASSWORD;
  $phpmailer->From =       SMTP_FROM;
  $phpmailer->FromName =   SMTP_FROMNAME;
  $phpmailer->Port =       SMTP_PORT;
  $phpmailer->SMTPAuth =   SMTP_AUTH;
  $phpmailer->SMTPSecure = SMTP_SECURE;
}

Explanation:

The add_action hook adds a function to be executed during the sending of an email in WordPress (which is when the mentioned phpmailer_init action is fired).

The $phpmailer values set in the send_smtp_email function set the SMTP settings for phpmailer (the default library for sending email in WordPress) to the values of constants defined in wp-config.php, allowing WordPress to send emails using the specified SMTP server and credentials.

2.2 In wp-config.php

Add these definitions to the section of the wp-config.php file where you define your other WordPress constants, typically near the top of the file. This makes it easier to understand and modify the SMTP settings in the future if needed.

// Define constants for SMTP settings
define( 'SMTP_HOST',     'smtp.example.com' );
define( 'SMTP_USER',     '[email protected]' );
define( 'SMTP_PASSWORD', 'smtp password' );
define( 'SMTP_FROM',     '[email protected]' );
define( 'SMTP_FROMNAME', 'e.g Website Name' );
define( 'SMTP_PORT',      '25' );
define( 'SMTP_AUTH',      true );
define( 'SMTP_SECURE',    'tls' );

If our WordPress site used Microsoft Outlook as its SMTP email server, as shown in the screenshot above, we would set our site’s wp-config.php values like this:

// Define constants for SMTP settings
define( 'SMTP_HOST',     'smtp.office365.com' );
define( 'SMTP_USER',     '[email protected]' );
define( 'SMTP_PASSWORD', 'Ms66o3wd|YmQs>k' );
define( 'SMTP_FROM',     '[email protected]' );
define( 'SMTP_FROMNAME', 'Cool Digs Website' );
define( 'SMTP_PORT',     '587' );
define( 'SMTP_AUTH',     true );
define( 'SMTP_SECURE',   'tls' );

Once the constants are defined, you can use them in your code snippets to set up WordPress to use SMTP without a plugin. Remember to save the wp-config.php file after making any changes.

Here’s what it looks like in wp-config.php:

SMTP without a plugin wp-config.php settings
wp-config.php with SMTP settings

Note

While you could avoid having two separate code snippets by putting your credentials in just one place (directly into the first code snippet above), putting them into wp-config.php makes for a more consistent and portable solution. Secrets on WordPress are best stored in the config file, and (if you place your code in functions.php) changing themes in the future won’t break your setup.

3. Test your site

The simplest way to test that email is working is to use the “Forgot Password” feature in the WordPress login screen:

  1. Log out of your WordPress account or open a new browser window in incognito or private mode.
  2. Navigate to your WordPress login page at yourdomain.com/wp-login.php or yourdomain.com/wp-admin.
  3. Click on the “Lost your password?” link.
  4. Enter the email address associated with your user account, or enter your username, and click the “Get New Password” button.

If the email setup is functioning correctly, you should receive a password reset email at the specified address. This indicates that your WordPress site is capable of sending emails.

You’re done!

With this snippet in place, your WordPress site is now able to send emails via any SMTP server without a plugin. If you want to run further email tests, check out the companion article How to test if WordPress can send emails.

If all you wanted to get from this article was how to configure WordPress to send emails without a plugin, you can stop here.

Going further: sending WordPress emails from code

If you want to send emails programmatically from your WordPress site, you can use the wp_mail() function. This function simplifies the process of sending emails compared to dealing with PHPMailer() directly, and allows you to customize the email content and headers.

Using wp_mail() function

The wp_mail() function accepts the following parameters:

  • $to (required): The recipient’s email address.
  • $subject (required): The subject of the email.
  • $message (required): The email content.
  • $headers (optional): An array or string of additional headers.
  • $attachments (optional): An array of file paths to be sent as attachments.

Here’s an example of how to use the wp_mail() function. If you don’t need a Reply-To address or attachments, simply remove those lines:

$to      = '[email protected]';
$subject = 'Email Subject';
$message = 'Hello, this is a test email from WordPress!';

$headers = array(
    'From: My Website <[email protected]>',
    'Reply-To: Reply Name <[email protected]>',
    'Content-Type: text/html; charset=UTF-8',
);

// Array of file paths to be attached
$attachments = array(
    WP_CONTENT_DIR . '/uploads/file1.pdf', // Path to the first attachment
    WP_CONTENT_DIR . '/uploads/file2.jpg', // Path to the second attachment
);

$send_email = wp_mail( $to, $subject, $message, $headers, $attachments );

if ( $send_email ) {
    echo 'Email sent successfully with Reply-To and attachments.';
} else {
    echo 'Email sending failed.';
}

Sending HTML emails

To send an HTML email, you need to set the Content-Type header to text/html. In the following example, the $headers array includes the Content-Type header with the appropriate value. You can now use HTML tags in your email content to style and format the email.

Here’s an example of sending an HTML email:

$to      = '[email protected]';
$subject = 'Email Subject';
$message = '
    <html>
    <head>
        <title>Email from WordPress</title>
    </head>
    <body>
        <h1>Hello!</h1>
        <p>This is a test HTML email sent from WordPress!</p>
    </body>
    </html>';

$headers = array(
    'From: My Website <[email protected]>',
    'Reply-To: Reply Name <[email protected]>',
    'Content-Type: text/html; charset=UTF-8',
);

$send_email = wp_mail( $to, $subject, $message, $headers );

if ( $send_email ) {
    echo 'HTML email sent successfully.';
} else {
    echo 'Email sending failed.';
}

Remember to include the opening and closing <html> and <body> tags in your email content when sending HTML emails. This will ensure proper rendering of the email in email clients.

Note that with the email configuration set up as explained in the previous sections, using the wp_mail() function as demonstrated here will automatically use the SMTP settings you defined in the wp-config.php file and the custom PHP code snippet. This means that when you send emails programmatically with wp_mail(), they will be sent through the SMTP server you defined with the credentials you provided.

Going even further: debugging the WordPress SMTP session

Sometimes, you may encounter issues when sending emails from your WordPress site using the SMTP server. In these cases, capturing the entire SMTP session can help you identify any anomalies or problems in the conversation between your WordPress server and the remote SMTP server. This information can be invaluable for troubleshooting email sending issues.

How to read an SMTP session log
Learn how to read an SMTP session log & uncover the secrets of email delivery! 📧 Perfect for troubleshooting & understanding WordPress email issues.
nanopo.st

To log the SMTP session, we need to delve deeper than the wp_mail() function can provide. We will go one level deeper, to the PHPMailer library, which is the default library used by WordPress to send emails.

To capture the SMTP session and write it to a local file, which you can then inspect, you can use the following code snippet:

// Set the debug handler function to capture the entire SMTP session
$phpmailer->Debugoutput = function( $str, $level ) use ( $phpmailer ) {
    // Create the smtp_logs directory within the wp-content folder if it doesn't exist
    $log_dir = WP_CONTENT_DIR . '/smtp_logs';
    if ( ! file_exists( $log_dir ) ) {
        mkdir( $log_dir, 0755, true );
    }

    // Define the log file name with a unique identifier (current timestamp with microseconds)
    $filename = $log_dir . '/smtp_log_' . date( 'Y-m-d_H-i-s' ) . '.log';

    // Write the debug output to the log file
    file_put_contents( $filename, $str );
};

This code snippet sets a custom debug handler function for the PHPMailer instance ($phpmailer) used by WordPress to send emails. The function captures the entire SMTP session and appends the debug output to a local file with a unique filename based on the current date and time (for example, smtp_log_2022-04-10_15-30-45.log). Each file will hold a separate SMTP session to make it easy to review. In a default WordPress setup, you’ll find the file under /wp-content/smtp-logs/.

To create the file, the snippet will first check if the smtp_logs directory exists in the wp-content folder. If it doesn’t, the mkdir() function will create the directory with the specified permissions (0755 in this case). Then, the debug output from the SMTP session will be appended to the log file within the smtp_logs directory.

The result should look something like this:

An SMTP session
An SMTP session

By capturing and analyzing the SMTP session, you can gain insights into any issues that might be causing email sending problems on your WordPress site. This advanced debugging technique can help you resolve email delivery issues and ensure that your site’s email functionality is working as expected.

Avoiding setting up SMTP altogether

However, if all you’re looking to do is set up a simple contact form and would prefer to avoid dealing with SMTP setup altogether, we have an alternative solution that might interest you. In another one of our guides, we delve into the process of creating a WordPress contact form without plugins​. This method is extremely simple and doesn’t require wrestling with SMTP servers or plugins, since it suggests usiing third-party form handling services, which can simplify the process and even provide additional features, such as seamless integration with services like Airtable and Mailchimp.


Questions? Post them below and we’ll update this article for clarity.

Leave a Reply

Your email address will not be published. Required fields are marked *