So as the title explains, when sending an HTML email with drupal_mail(), email comes with no HTML tags.

    $module = 'module';
    $key = 'contact_message';
    $language = language_default();
    $params = array();
    $email = 'sender@email.com';
    $from = variable_get('site_mail', 'admin@example.com');
    $send = TRUE;
    $message = drupal_mail($module, $key, $email, $language, $params, $from, $send);
    $message['headers']['Content-Type'] = 'text/html; charset=UTF-8';
    $message['subject'] = 'Test';
    $message['body'] = array();
    $message['body'][] = '<a href="#">Testing anchor in mail</a>';
    $system = drupal_mail_system($module, $key);
    $message = $system->format($message);
    $message['result'] = $system->mail($message);

And when recieving the email, and viewing the source:

Message-Id: <201305090722.r497MLAV005654@test.server>
X-Authentication-Warning: testserver : www-data set sender to sender@email.com using -f
To: from@email.com
Subject: Test
X-PHP-Originating-Script: 1000:system.mail.inc
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8Bit
X-Mailer: Drupal
Sender: sender@email.com
From: from@email.com

Testing anchor in mail [1]

[1] #

So you can see that any HTML tags were stripped. And it doesn't matter what HTML tags I put in body.

I thought it might be related to Text Fomats, but I have "Filtered HTML" and "Full HTML" active filters with any permissions.

The thing confused me were the Ubercart invoices. At first they were sent with HTML, and then at some point it stopped. They were received plain text. After digging a bit @develkar answer, I've found this in one of ubercart updates:

 * Installs HTML Mail System for Ubercart.
function uc_store_update_7004() {
  // Set mail handler for all Ubercart modules
      variable_get('mail_system', array('default-system' => 'DefaultMailSystem')),
        'uc_cart'  => 'UbercartMailSystem',
        'uc_order' => 'UbercartMailSystem',
        'uc_file'  => 'UbercartMailSystem',
        'uc_roles' => 'UbercartMailSystem',
        'uc_stock' => 'UbercartMailSystem',
        'uc_store' => 'UbercartMailSystem',

I guess that at some point, one of installed modules (I suspect SMTP module) overridden this variable, and that's why emails were coming plain text. After running this update manually again, Ubercat invoices are HTML again.

For the rest of emails, I'll have to install some modules as suggested in other answers.



drupal_mail(), by default sends a mail as plain text.

If you print out the array $message['headers'], you will get something like:

    'MIME-Version' => '1.0',
    'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer' => 'Drupal',

As you can see, the Content-Type in the mail header is text/plain; charset=UTF-8; format=flowed; delsp=yes. You can try by modifying this header in hook_mail_alter(), you could use one of the modules which allows you to send the mail as HTML, like HTML Mail, or Mime Mail.


Following the comments by @Ayesh and @alechko and after looking into the APIs, I found out that the headers are not the only reason for sending the mail as plain text. Because drupal_mail() internally makes a call to drupal_mail_system(), which returns an object that implements the MailSystemInterface interface. The format() method implemented by drupal_mail_system() is responsible for stripping out the HTML from the emails. So, even if the headers of the mail show the formats to be HTML, the mails would be sent as plain text only. So, I guess one could not send an HTML mail using drupal_mail(). You should look for some other alternative (module) mentioned above.

| improve this answer | |
  • Even though you set the ctype, Drupal strips all HTML tags in the preparation step (can't remember method name). – AyeshK May 9 '13 at 7:46
  • If you'd look in my output of received mail, you'd see that: Content-Type: text/html; charset=UTF-8 – alechko May 9 '13 at 7:55
  • @AyeshK You are right. I have made the edit, the function responsible for stripping HTML is drupal_mail_sytem(). – AjitS May 9 '13 at 8:11
  • @alechko Please see for the edit. – AjitS May 9 '13 at 8:11
  • Thanks @develkar :) . Actually the header change does the trick in D6, and I recently had to create a custom mail class to handle HTML emails. Still using drupal_mail, and overriding the rendering methods only. – AyeshK May 9 '13 at 8:19

In hook_mail also,you can define the headers as text/html,then you will get mail as an html format,as for example:

$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
| improve this answer | |

Give a try with HTML Mail module installed and configured.

Lets you theme your messages the same way you theme the rest of your website.

| improve this answer | |
  • I tried and it worked, but I was looking for native solution, because in the past, same installation was sending HTML emails, and after some point I've noticed that the emails came stripped. I had no "Helper modules" in the past. – alechko May 9 '13 at 7:52

It doesn't matter what the header Content-Type is, Drupal's default mail system converts html to plain text. See DefaultMailSystem::format() in mail.inc

public function format(array $message) {
// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);
// Convert any HTML to plain-text.
$message['body'] = drupal_html_to_text($message['body']);
// Wrap the mail body for sending.
$message['body'] = drupal_wrap_mail($message['body']);
return $message;


To send allow html in the message body you will need to:

  1. create a custom mail system class that implements MailSystemInterface that has a format method that does not convert html to plain text
  2. Include that new class in your modules.info file
  3. Let Drupal know you want to use your custom mail system class

    variable_set('mail_system', array('default-system' => 'ExampleMailSystem'));

  4. Set the Content-Type header from "text/plain" to "html/plain"

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

This documentation on d.o. does a good job of describing the solution and providing an example.


| improve this answer | |
  • This looks doable. Would it be possible to switch the mail_system just on particular occassions, like in a webform submission handler for only some webforms ? – commonpike Dec 28 '17 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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