WordPress: Sending HTML formatted emails using the wp_mail() function

3
3540

If you are working on sending emails from your plugin or theme in WordPress it is a very good idea to use the wp_mail() function instead of trying to directly do it with PHP or other means. The reason for this is that the function provides filters for controlling the email content and also works well with WordPress plugins that are created to handle email routing, such as the various SMTP plugins.

By default wp_mail() sends email as plain text with the mime type of “text/plain” and you may have a need to send email in HTML format.

We can simply change the mime type to “text/html”  so that subsequent emails sent after adding a filter to “wp_mail_content_type” will change the mime header to “text/html” for all email going forward.

function te_wp_mail_html(){
    return "text/html";
}
add_filter( 'wp_mail_content_type','te_wp_mail_html' );

That’s it, now all email sent from WordPress will be sent as HTML email.

One important point to remember is that as mentioned previously WordPress by default sends emails in text format.

As such it happens to wrap its password reset link with <> symbols. So if you send emails with a text/html header, this password reset link will get converted to HTML and no longer be visible in the email, as a result you must set the headers back to text by removing the filter override after you send the email.

Lets look at a few examples how you may use the code in such instance.

Note: the following code snippets would be used in either a custom plugin or the functions.php file of your theme.

Example 1

We have a separate function “te_wp_mail_html” where we set the MIME type, and call that using the “wp_mail_content_type” filter before sending the email. Once the email has been sent with wp_mail(), we remove the function by calling remove_filter on “wp_mail_content_type“. I prefer this method as it allows more organization of the code and you can use “te_wp_mail_html” in other code blocks as well.

In the example below we assume some processing on a form submission and ‘some_event_action’ which maybe an action/filter available based on your form plugin, so please adapt the code accordingly.

function te_form_submission_process(){
    //Your submission processing

    //Add the filter before calling the wp_mail() function
    add_filter( 'wp_mail_content_type','te_wp_mail_html' );

    //Send the email with required parameters
    wp_mail( $to, $subject, $message, $headers, $attachments );

    //Remove the filter we added so that we dont affect other processes
    remove_filter( 'wp_mail_content_type','te_wp_mail_html' );
}
add_filter( 'some_event_action','te_form_submission_process' );


//Our override function to set the email MIME type to HTML
function te_wp_mail_html(){
    return "text/html";
}
​

Example 2

Instead of using a separate function as the previous example, we can set and unset the mime type directly in the processing function.

function te_form_submission_process(){
    //Your submission processing

    //Set the MIME type of wp_mail_content_type directly without external function
    add_filter('wp_mail_content_type', function() { return "text/html"; } );

    //Send the email with required parameters
    wp_mail( $to, $subject, $message, $headers, $attachments );

    //Set the MIME type of wp_mail_content_type directly without external function
    add_filter('wp_mail_content_type', function() { return "text/plain"; } );
}
add_filter( 'some_event_action','te_form_submission_process' );

Example 3

Set the header as part of the $header parameter array right in the wp_mail() function. This will only affect the current call to the function and all default WordPress functionality will remain the same.

function te_form_submission_process(){
    //Your submission processing

    wp_mail( $to, $subject, $message, array('Content-Type: text/html; charset=UTF-8'), $attachments );
}
add_filter( 'some_event_action','te_form_submission_process' );

3 COMMENTS

  1. Hi James, thank you for your question, the code snippets would be used in a custom plugin or the functions.php file of your theme, you would have to modify them to use the appropriate action though.

    I have also updated the article with note.

LEAVE A REPLY

Please enter your comment!
Please enter your name here