On /admin/settings/email, when the HTML Email Template field is set to a valid template, all system messages are sent using it. They inject the content of the messages inside the {% block main %}{{body}}{% endblock %} variable.

From a custom plugin, setHtmlBody doesn't inject the content inside it. It takes its value as the whole template value instead of only replacing the {{body}} variable.



use craft\mail\Message;

$message = new Message();
$message->setSubject("Hello world.");
$message->setHtmlBody("Hello world.");

How can I send this email using the custom HTML email template specified in my CP Email Settings?

I could copy-paste the whole file content of my custom template inside the setHtmlBody, but it doesn't seems to be a clean way...

1 Answer 1


There are different ways

Extending the E-mail template in your template

This could be your email template emails/_someMail

{% extends 'path/of/your/layout-same-as-you-inserted-in-your-cp' %}

{% block main %}Hello World{% endblock %}

And in your PHP file

use craft\mail\Message;

$message = new Message();
$message->setSubject("Hello world.");

Render the correct template from the beginning

You can do exactly the same as Craft does in it's function - but I would suggest the first way

$systemMessage = Craft::$app->getSystemMessages()->getMessage('test_email', $message->language);
$subjectTemplate = $systemMessage->subject;
$textBodyTemplate = $systemMessage->body;

// Use the site template mode
$view = Craft::$app->getView();
$templateMode = $view->getTemplateMode();

// Use the message language
$language = Craft::$app->language;
if ($message->language !== null) {
    Craft::$app->language = $message->language;

$settings = Craft::$app->getSystemSettings()->getEmailSettings();
$variables = ($message->variables ?: []) + [
        'emailKey' => $message->key,
        'fromEmail' => $settings->fromEmail,
        'fromName' => $settings->fromName,

// Render the subject and textBody
$subject = $view->renderString($subjectTemplate, $variables);
$textBody = $view->renderString($textBodyTemplate, $variables);

// Is there a custom HTML template set?
if (Craft::$app->getEdition() === Craft::Pro && Craft::$app->getMailer()->template) {
    $template = Craft::$app->getMailer()->template;
} else {
    // Default to the _special/email.html template
    $template = '_special/email';

$e = null;
try {
    $htmlBody = $view->renderTemplate($template, array_merge($variables, [
        'body' => Template::raw(Markdown::process($textBody)),
} catch (TemplateLoaderException $e) {
    // Clean up before throwing

// Set things back to normal
Craft::$app->language = $language;

if ($e !== null) {
    throw $e;

  • Thank you so much Robin. I always appreciate your relevant answers. Sep 19, 2018 at 7:58
  • SO AWSM - thanks heaps Apr 14 at 14:34

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.