How To Replace wp_mail Function In WordPress

wall rack filled with paper document lot

To replace the WordPress wp_mail function and send email using your own method, you have two options:

  1. (RECOMMENDED) Use the modern WordPress version 5.7+ pre_wp_mail hook.
  2. Replace the wp_mail() functions entirely.

The main reasons to replace the wp_mail function are:

  1. You plan to use a service like Mailgun, Postmark, AWS SES, SendGrid, or another third-party email sending service. And, for your purposes, you prefer not to use your preferred email sending provider’s official WordPress plugin or plugin like WP Mail SMTP.
  2. You need a way to test sending emails without sending them to a real mailbox using WordPress core.
  3. You need to completely replace the WordPress email sending system to keep WordPress from sending emails at all.

Dare To Code

icon send thick Get the tips, links, and tricks on full-stack PHP development in your inbox with monthly emails from Kevin Dees.

Name(Required)
This field is for validation purposes and should be left unchanged.

The Modern Way With pre_wp_mail

To replace and override the wp_mail() function using the filter pre_wp_mail is the best and most modern method. Using this method will future-proof your override.

At the top of your WordPress theme’s functions.php file add the following code:

// Your theme's functions.php
add_filter( 'pre_wp_mail', function($null, $atts) {
    $message = $atts['message'];
    $to = $atts['to'];
    $subject = $atts['subject'];
    $headers = $atts['headers'];
    $attachments = $atts['attachments'];
    
    // Add your code here

    return true;
}, 10, 2);

Adding these lines of code will “Short-circuit” the internal WordPress email sending system and cause it to prefer your method over PHPMailer. Here are a few things you must do within the filter pre_wp_mail hook:

  1. Ensure the function returns a bool value of true or false. True if the email was sent successfully. Do not return null! Returning a bool type value for this filter will tell the WordPress wp_mail function that you want to replace its core mail sending functionality.
  2. Do not reapply the apply_filters( ‘wp_mail’, …) hook within your new filter.
  3. You will need to implement your own email sending service within the function.

Full Replacement

This method, the full replacement method, was the only option before WordPress 5.7 released the pre_wp_mail hook. Therefore, if you are using WordPress version 5.7+, you should use the pre_wp_mail hook.

To replace the wp_mail() function, declare the wp_mail() function in your theme’s functions.php file immediately. Doing this will cause WordPress core to prefer your version of the function instead of its own.

// Your theme's functions.php
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
    $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );

    // Add your code here    

    return true;
}

If you are replacing the wp_mail() function entirely this way, here are a few things you will need to make sure you do:

  1. Ensure the function returns a bool value of true or false. True if the email was sent successfully.
  2. Precisely copy all the same function call signature. That is, use the same function arguments exactly as core defines them.
  3. Ensure you use the apply_filters( ‘wp_mail’, …) hook within your new version. If you don’t do this, you are likely to break WordPress.
  4. You will need to implement your email sending service within the function.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.