73

Is there an action_hook or something similar that could help me achieve this?

I tried adding markup in a PHP string variable and just fired off an email with the wp_mail() function like so:

$email_to = '[email protected]';
$email_subject = 'Email subject';
$email_body = "<html><body><h1>Hello World!</h1></body></html>";
$send_mail = wp_mail($email_to, $email_subject, $email_body);

But it showed up as plain text?

Any ideas?

1

5 Answers 5

80

from wp_mail codex page:

The default content type is 'text/plain' which does not allow using HTML. However, you can set the content type of the email by using the 'wp_mail_content_type' filter.

// In theme's functions.php or plug-in code:

function wpse27856_set_content_type(){
    return "text/html";
}
add_filter( 'wp_mail_content_type','wpse27856_set_content_type' );
12
  • 2
    Hmm sounds useful. Just a question, any particular reason why you named your function wpse27856_set_content_type?
    – racl101
    Commented Sep 6, 2011 at 21:31
  • 27
    No, it's just a unique name based on the id of this particular question. wpse = wp stachexchange, 27856 is the id of this question in the URL. I just do that to avoid potential collisions if people copy/paste code out of here.
    – Milo
    Commented Sep 6, 2011 at 21:45
  • 3
    You can also just include the Content-Type in your email headers. Check out how the Notifly plugin does it.
    – Otto
    Commented Sep 7, 2011 at 0:29
  • 2
    This will break your password reset email, because the reset link is wrapped in <>. Commented Oct 24, 2017 at 6:08
  • 2
    @SimonJosefKok, if I'm reading this bug report correctly, the issue of breaking password reset emails is resolved as of WordPress 5.4. Sounds like they decided to remove the angle brackets from the email address. core.trac.wordpress.org/ticket/23578#comment:24
    – Mark Berry
    Commented Feb 11, 2020 at 1:22
173

As an alternative, you can specify the Content-Type HTTP header in the $headers parameter:

$to = '[email protected]';
$subject = 'The subject';
$body = 'The email body content';
$headers = array('Content-Type: text/html; charset=UTF-8');

wp_mail( $to, $subject, $body, $headers );
6
  • 7
    This works better as the add_filter sometimes shows as attachment. Thanks for sharing!
    – deepakssn
    Commented Feb 17, 2018 at 18:54
  • 6
    This is the generally best way to-do this. The top answer will interfere with other plugins and cause problems. Commented Dec 6, 2019 at 19:12
  • 1
    This should be the accepted answer Commented Sep 27, 2020 at 18:49
  • 1
    This answer should be the accepted! Commented Jun 30, 2021 at 20:46
  • It appears to my reading of the wp_mail() source that the headers cannot be an array, but needs to be in the form of 'to: [email protected]'. Still trying to test this, and I'll bow to more experienced developers to check my accuracy. Commented Aug 5, 2022 at 22:37
14

Don't forget to remove the content type filter after you use the wp_mail function. Following the accepted answer naming you should do this after wp_mail is executed:

remove_filter( 'wp_mail_content_type','wpse27856_set_content_type' );

Check this ticket here - Reset content-type to avoid conflicts -- http://core.trac.wordpress.org/ticket/23578

1
  • 18
    This should be a comment, not an answer, no?
    – Bob Diego
    Commented Jul 26, 2017 at 14:31
2

Another easy way I'm going to share below. Even you can style your mail body as your wish. Maybe it's helpful for you.

$email_to = '[email protected]';
$email_subject = 'Email subject';

// <<<EOD it is PHP heredoc syntax
$email_body = <<<EOD
This is your new <b style="color: red; font-style: italic;">password</b> : {$password}
EOD;

$headers = ['Content-Type: text/html; charset=UTF-8'];

$send_mail = wp_mail( $email_to, $email_subject, $email_body, $headers );

More about PHP heredoc syntax https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

1

Use ob_start, because this will allow you to use WP variables/functions like bloginfo etc.

make a PHP file and paste your HTML in that file(use wp variables inside that php file if needed).

Use the below code:

 $to = 'Email Address';
 $subject = 'Your Subject';

 ob_start();
 include(get_stylesheet_directory() . '/email-template.php');//Template File Path
 $body = ob_get_contents();
 ob_end_clean();

 $headers = array('Content-Type: text/html; charset=UTF-8','From: Test <[email protected]>');
 wp_mail( $to, $subject, $body, $headers );

this will keep your code clean and due to ob_start we will also save the time of loading the file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.