🔥 Just Launched! Werra Premium Template for HyväSee it in Action

How to Use phtml File in Email Template in Magento 2

By Sanjay JethvaUpdated on May 22, 2025 4 min read

Magento 2 store owners send emails to customers for not only marketing purposes but also for sending the order, shipping, and invoice details.

For branding purposes, the merchants use customize email templates over the default one. When a customer receives emails having the store name and logo with a well-organized email template design, it makes a great impression.

To check the email template design while creating, Magento 2 offers the preview option. That shows how the email template design will look in the frontend. However, the process is complicated and time-consuming as well.

Here are the steps that you have to follow for checking the output of the design of the email template from the admin panel:

Email template grid

Login to Magento 2 admin panel

Visit Marketing > Communications > Email Templates 

Click on Add New Template

Select and click on Load Template

Email template preview

Now, click on Preview Template to see the changes that you have made.

However, the programmatic method to use phtml file in Email template in Magento 2 can be a better option that eliminates the above steps and removes the admin’s dependency.

Steps to Use phtml File in Email Template in Magento 2

Create app/code/Vendor/Extension/registration.php

<?php 
Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE, 
    'Vendor_Extension', 
    __DIR__
);

Create app/code/Vendor/Extension/etc/module.xml

<? xml version = "1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Extension" setup_version="1.0.0">
    </module>
</config>

Create app/code/Vendor/Extension/etc/frontend/routes.xml

<? xml version = "1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="extension" frontName="extension">
            <module name="Vendor_Extension"/>
        </route>
    </router>
</config>

Create app/code/Vendor/Extension/Controller/Index/Index.php

<?php namespace Vendor\Extension\Controller\Index;

use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\App\Action\Action;

class Index extends Action
{
    protected $resultPageFactory;

    public function __construct(Context $context, PageFactory $resultPageFactory)
    {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    public function execute()
    {
        return $resultPage = $this->resultPageFactory->create();
    }
}

Create app/code/Vendor/Extension/view/frontend/layout/extension_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Vendor\Extension\Block\Extension" name="extension_index_index"
                   template="Vendor_Extension::template_file.phtml"/>
        </referenceContainer>
    </body>
</page>

Create app/code/Vendor/Extension/Block/Extension.php

<?php namespace Vendor\Extension\Block;

use Magento\Framework\View\Element\Template;

class Extension extends Template
{
    protected $_template = 'Vendor_Extension::template_file.phtml';
}

Create app/code/Vendor/Extension/view/frontend/templates/template_file.phtml

This is the content of the phtml file

Create app/code/Vendor/Extension/view/frontend/email/email_template.html

<!--@subject Use phtml file in email template @-->
<!--@vars {"store url=\"\"":"Store Url", "skin url=\"images/logo_email.gif\" _area='frontend'":"Email Logo Image"} @-->
<!--@styles body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; } @--> {{template
config_path="design/email/header_template"}} 
{{var template|raw}}

Create app/code/Vendor/Extension/etc/email_templates.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="my_custom_email_template"
              label="Use phtml file in email template"
              file="email_template.html"
              type="html"
              module="Vendor_Extension"
              area="frontend"
    />

</config>

Create app/code/Vendor/Extension/Helper/Data.php

<?php

namespace Vendor\Extension\Helper;

use Magento\Framework\App\Area;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\View\Element\AbstractBlock;
use Magento\Framework\View\Element\Template;
use Magento\Store\Model\App\Emulation;
use Vendor\Extension\Block\Extension;

class Data extends Template
{

    private $transportBuilder;

    private $appEmulation;

    public function __construct(
        Emulation $appEmulation,
        TransportBuilder $transportBuilder,
        Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->transportBuilder = $transportBuilder;
        $this->appEmulation = $appEmulation;
    }

    /**
     * Create block instance
     *
     * @param string|AbstractBlock $block
     * @return AbstractBlock
     * @throws LocalizedException
     */
    public function createBlock($block)
    {
        if (is_string($block)) {
            if (class_exists($block)) {
                $block = $this->_layout->createBlock($block);
            }
        }
        if (!$block instanceof AbstractBlock) {
            throw new LocalizedException(__('Invalid block type: %1', $block));
        }
        return $block;
    }
    //call this function to send mail
    public function sendEmail()
    {
        // this is an example and you can change template id,fromEmail,toEmail,etc as per your need.
        $templateId = 'my_custom_email_template'; // template id
        $fromEmail = '[email protected]';  // sender Email id
        $fromName = 'From Name';             // sender Name
        $toEmail = '[email protected]'; // receiver email id

        try {

            $block = $this->createBlock(Extension::class);//pass reference of block class here, connected with phtml file
            // make sure in your block class there is
            // $_template variable exist which specifies the reference to the phtml file like
            // protected $_template = 'Vendor_Module::template.phtml';
            $template = $this->_appState->emulateAreaCode(
                Area::AREA_FRONTEND,
                [$block, 'toHtml']
            ); // pass this variable as template variable of email template.
            // template variables pass here
            $templateVars = [
                'template' => $template
            ];
            // use this template variable in email template as {{var template|raw}}
            $storeId = $this->_storeManager->getStore()->getId();

            $from = ['email' => $fromEmail, 'name' => $fromName];
            $this->inlineTranslation->suspend();

            $templateOptions = [
                'area' => Area::AREA_FRONTEND,
                'store' => $storeId
            ];
            $transport = $this->transportBuilder->setTemplateIdentifier($templateId)
                ->setTemplateOptions($templateOptions)
                ->setTemplateVars($templateVars)
                ->setFrom($from)
                ->addTo($toEmail)
                ->getTransport();
            $transport->sendMessage();
            $this->inlineTranslation->resume();
        } catch (\Exception $e) {
            $this->_logger->info($e->getMessage());
        }
    }
}

That’s it.

Do consider sharing this article with Magento Community via social media.

Thank you.

Sanjay Jethva Full Image
Article bySanjay Jethva

Sanjay is the co-founder and CTO of Meetanshi with hands-on expertise with Magento since 2011. He specializes in complex development, integrations, extensions, and customizations. Sanjay is one the top 50 contributor to the Magento community and is recognized by Adobe. His passion for Magento 2 and Shopify solutions has made him a trusted source for businesses seeking to optimize their online stores. He loves sharing technical solutions related to Magento 2 & Shopify.