<p>It's not clear exactly in what context you're sending your email (i.e., whether it's in response to some event on the front/back end), but here's an example of how I'd send an email in a plugin or module. Key here is that in order to access your Craft <code>templates</code> directory, you need to switch the template mode from CP to SITE. You can then use <code>setHtmlBody</code> and <code>renderTemplate</code> to parse your template as the email's body. The <code>renderTemplate</code> method allows you to pass some variables to the template too like this:</p>
<pre class="lang-php prettyprint-override"><code>// need to switch template mode to use 'SITE' (as opposed to CP).
$oldMode = Craft::$app-&gt;view-&gt;getTemplateMode();
Craft::$app-&gt;view-&gt;setTemplateMode(View::TEMPLATE_MODE_SITE);

$mailer = Craft::$app-&gt;getMailer();
$mailer-&gt;compose()
    -&gt;setTo($this-&gt;email)
    -&gt;setSubject('Product information from Acme Corp')
    -&gt;setHtmlBody(
        Craft::$app-&gt;getView()-&gt;renderTemplate('emails/productEmail.twig', [
            'productId' =&gt; $this-&gt;productId,
            'siteHandle' =&gt; $this-&gt;siteHandle,
            'productImg' =&gt; $this-&gt;productImg,
            'videoThumb' =&gt; $this-&gt;videoThumb,
        ])
    )
    -&gt;send();

// put the template mode back again in case more code needs to execute...
Craft::$app-&gt;view-&gt;setTemplateMode($oldMode);
</code></pre>

CC BY-SA 4.0
2021-06-30T10:17:28.993Z
2021-06-30T10:25:39.770Z
2021-06-30T10:25:39.770Z
James Smith
<p>I have a throuble with email sending from Craft CMS 3.</p>
<p>For example, I'm trying to send email based on a custom view placed in mail/test.php. So I wrote this code:</p>
<pre><code>    \Craft::$app-&gt;mailer
        -&gt;compose('test', [])
        -&gt;setTo('test@domain.local')
        -&gt;setSubject('Test message')
        -&gt;send();
</code></pre>
<p>In runtime I've got an error:</p>
<pre><code>Exception 'yii\base\ViewNotFoundException' with message 'The view file does not exist: /app/vendor/craftcms/cms/src/mail/test.php'

in /app/vendor/yiisoft/yii2/base/View.php:233

Stack trace:
#0 /app/vendor/yiisoft/yii2/base/View.php(156): yii\base\View-&gt;renderFile('/app/vendor/cra...', Array, Object(craft\mail\Mailer))
#1 /app/vendor/yiisoft/yii2/mail/BaseMailer.php(302): yii\base\View-&gt;render('test', Array, Object(craft\mail\Mailer))
#2 /app/vendor/yiisoft/yii2/mail/BaseMailer.php(194): yii\mail\BaseMailer-&gt;render('test', Array, 'layouts/html')
#3 /app/modules/subscription/commands/TestController.php(149): yii\mail\BaseMailer-&gt;compose('test', Array)
#4 [internal function]: modules\subscription\commands\TestController-&gt;actionTest4()
#5 /app/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#6 /app/vendor/yiisoft/yii2/base/Controller.php(181): yii\base\InlineAction-&gt;runWithParams(Array)
#7 /app/vendor/yiisoft/yii2/console/Controller.php(184): yii\base\Controller-&gt;runAction('test4', Array)
#8 /app/vendor/craftcms/cms/src/console/Controller.php(192): yii\console\Controller-&gt;runAction('test4', Array)
#9 /app/vendor/yiisoft/yii2/base/Module.php(534): craft\console\Controller-&gt;runAction('test4', Array)
#10 /app/vendor/yiisoft/yii2/console/Application.php(181): yii\base\Module-&gt;runAction('subscription/te...', Array)
#11 /app/vendor/craftcms/cms/src/console/Application.php(89): yii\console\Application-&gt;runAction('subscription/te...', Array)
#12 /app/vendor/yiisoft/yii2/console/Application.php(148): craft\console\Application-&gt;runAction('subscription/te...', Array)
#13 /app/vendor/yiisoft/yii2/base/Application.php(392): yii\console\Application-&gt;handleRequest(Object(craft\console\Request))
#14 /app/craft(27): yii\base\Application-&gt;run()
#15 {main}
</code></pre>
<p>I suppose Craft looks for my view in a wrong place. There are no view in the vendor dir. After that I added some config into config/app.php to fix this issue:</p>
<pre><code>    'components' =&gt; [
        // ............
        'mailer' =&gt; function () {
            $config = craft\helpers\App::mailerConfig();
            $config['viewPath'] = '@root/mail'; // here we tell to Craft where our email views are
            return Craft::createObject($config);
        },
        // ............
    ],
</code></pre>
<p>And the letter was successfully sent. It seems like Craft CMS has broken mailer out of the box. Or did I do something wrong?</p>

<craft3><emails>
Wrong default mail view directory?
# Wrong default mail view directory?

(Asked by: username_0 on 2021-06-29)

I have a throuble with email sending from Craft CMS 3.
For example, I'm trying to send email based on a custom view placed in mail/test.php. So I wrote this code:
    \Craft::$app->mailer
        ->compose('test', [])
        ->setTo('test@domain.local')
        ->setSubject('Test message')
        ->send();

In runtime I've got an error:
Exception 'yii\base\ViewNotFoundException' with message 'The view file does not exist: /app/vendor/craftcms/cms/src/mail/test.php'

in /app/vendor/yiisoft/yii2/base/View.php:233

Stack trace:
#0 /app/vendor/yiisoft/yii2/base/View.php(156): yii\base\View->renderFile('/app/vendor/cra...', Array, Object(craft\mail\Mailer))
#1 /app/vendor/yiisoft/yii2/mail/BaseMailer.php(302): yii\base\View->render('test', Array, Object(craft\mail\Mailer))
#2 /app/vendor/yiisoft/yii2/mail/BaseMailer.php(194): yii\mail\BaseMailer->render('test', Array, 'layouts/html')
#3 /app/modules/subscription/commands/TestController.php(149): yii\mail\BaseMailer->compose('test', Array)
#4 [internal function]: modules\subscription\commands\TestController->actionTest4()
#5 /app/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#6 /app/vendor/yiisoft/yii2/base/Controller.php(181): yii\base\InlineAction->runWithParams(Array)
#7 /app/vendor/yiisoft/yii2/console/Controller.php(184): yii\base\Controller->runAction('test4', Array)
#8 /app/vendor/craftcms/cms/src/console/Controller.php(192): yii\console\Controller->runAction('test4', Array)
#9 /app/vendor/yiisoft/yii2/base/Module.php(534): craft\console\Controller->runAction('test4', Array)
#10 /app/vendor/yiisoft/yii2/console/Application.php(181): yii\base\Module->runAction('subscription/te...', Array)
#11 /app/vendor/craftcms/cms/src/console/Application.php(89): yii\console\Application->runAction('subscription/te...', Array)
#12 /app/vendor/yiisoft/yii2/console/Application.php(148): craft\console\Application->runAction('subscription/te...', Array)
#13 /app/vendor/yiisoft/yii2/base/Application.php(392): yii\console\Application->handleRequest(Object(craft\console\Request))
#14 /app/craft(27): yii\base\Application->run()
#15 {main}

I suppose Craft looks for my view in a wrong place. There are no view in the vendor dir. After that I added some config into config/app.php to fix this issue:
    'components' => [
        // ............
        'mailer' => function () {
            $config = craft\helpers\App::mailerConfig();
            $config['viewPath'] = '@root/mail'; // here we tell to Craft where our email views are
            return Craft::createObject($config);
        },
        // ............
    ],

And the letter was successfully sent. It seems like Craft CMS has broken mailer out of the box. Or did I do something wrong?

**Tags:** craft3, emails

---

## 1 answers

### Answer by username_1 on 2021-06-30. Score: 1 | Accepted answer

It's not clear exactly in what context you're sending your email (i.e., whether it's in response to some event on the front/back end), but here's an example of how I'd send an email in a plugin or module. Key here is that in order to access your Craft templates directory, you need to switch the template mode from CP to SITE. You can then use setHtmlBody and renderTemplate to parse your template as the email's body. The renderTemplate method allows you to pass some variables to the template too like this:
// need to switch template mode to use 'SITE' (as opposed to CP).
$oldMode = Craft::$app->view->getTemplateMode();
Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);

$mailer = Craft::$app->getMailer();
$mailer->compose()
    ->setTo($this->email)
    ->setSubject('Product information from Acme Corp')
    ->setHtmlBody(
        Craft::$app->getView()->renderTemplate('emails/productEmail.twig', [
            'productId' => $this->productId,
            'siteHandle' => $this->siteHandle,
            'productImg' => $this->productImg,
            'videoThumb' => $this->videoThumb,
        ])
    )
    ->send();

// put the template mode back again in case more code needs to execute...
Craft::$app->view->setTemplateMode($oldMode);


---

