Magento 2: How to Set a Theme on a Specific Page
Learn how to apply a different Magento theme to a specific frontend page using a custom module, observer, and route configuration.
Overview
Magento 2 allows developers to assign different themes to different storefronts. However, there are situations where you may want to display a completely different theme for only one specific page. In this tutorial, we'll create a custom route and use an observer to dynamically switch the theme when a user visits that page.
Step 1: Create routes.xml
Create the following file:
<?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="frontroute" frontName="frontroute">
<module name="Vendor_Extension"/>
</route>
</router>
</config>
This route creates a custom frontend URL: /frontroute/index/index
Step 2: Create Controller
<?php
namespace Vendor\Extension\Controller\Index;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\PageFactory;
class Index implements HttpGetActionInterface
{
protected $resultPageFactory;
public function __construct(PageFactory $resultPageFactory)
{
$this->resultPageFactory = $resultPageFactory;
}
public function execute(): ResultInterface
{
return $this->resultPageFactory->create();
}
}
Step 3: Create Layout File
<?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
name="index.index"
class="Vendor\Extension\Block\Index\Index"
template="Vendor_Extension::index/index.phtml"/>
</referenceContainer>
</body>
</page>
Step 4: Create Template File
<?php
/**
* @var $block \Vendor\Extension\Block\Index\Index
*/
?>
<h2>This page is Magento Blank theme.</h2>
Step 5: Create Block Class
<?php
namespace Vendor\Extension\Block\Index;
class Index extends \Magento\Framework\View\Element\Template
{
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
}
Step 6: Create Event Configuration
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="layout_load_before">
<observer
name="observer_name"
instance="Vendor\Extension\Observer\SetThemePage"/>
</event>
</config>
Step 7: Create Observer Class
<?php
namespace Vendor\Extension\Observer;
use Magento\Framework\App\Request\Http;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\View\DesignInterface;
class SetThemePage implements ObserverInterface
{
private Http $request;
private DesignInterface $design;
public function __construct(
Http $request,
DesignInterface $design
) {
$this->request = $request;
$this->design = $design;
}
public function execute(Observer $observer): void
{
$pathInfo = $this->request->getPathInfo();
if (substr($pathInfo, 0, 11) === '/frontroute') {
$this->design->setDesignTheme('Magento/blank');
}
}
}
Deploy Changes
Run the following Magento commands:
php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy -f
php bin/magento setup:di:compile
php bin/magento cache:flush
Result
After completing the above steps, when users visit:
Magento will automatically load the Magento Blank Theme only for this page while the rest of the storefront continues using the default theme.
Important Notes
- Replace Magento/blank with your custom theme if needed.
- Ensure your custom Theme is enabled.
- Clear Magento cache after changing themes.
- For production environments, always redeploy static content after theme changes.