How to create a controller and its actions in Magento2
Controllers are a core part of Magento 2 module development and any PHP MVC framework. A controller receives the request, processes it (or delegates to other layers), and returns a response (usually a page).
In Magento 2, controllers live under the Controller folder of your
module and contain execute() methods. There are two types:
- Frontend controllers – for storefront routes
- Backend controllers – for adminhtml routes (with permission checks)
1. How a Controller Works
A typical URL in Magento 2 looks like:
http://example.com/route_name/controller/action
- route_name – defined in
routes.xml(frontName) - controller – folder inside
Controller - action – PHP class with an
execute()method
The front controller Magento\Framework\App\FrontController receives
the request and loops through routers to find a matching controller action:
foreach ($this->_routerList as $router) {
try {
$actionInstance = $router->match($request);
// ...
} catch (\Exception $e) {
// handle exception
}
}
When an action is found, its execute() method is called.
2. Steps to Create a Frontend Controller
Basic steps:
- Step 1: Create
routes.xml - Step 2: Create controller class
- Step 3: Create layout file
- Step 4: Create block class
- Step 5: Create template file
- Step 6: Flush Magento cache
- Step 7: Test your new controller
Step 1: routes.xml
Define the frontend route in
app/code/Hikmadh/HelloWorld/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="helloworld" frontName="helloworld">
<module name="Hikmadh_HelloWorld" />
</route>
</router>
</config>
Step 2: Controller Class
Create the controller file
app/code/Hikmadh/HelloWorld/Controller/Index/Index.php:
<?php
namespace Hikmadh\HelloWorld\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
/**
* @var PageFactory
*/
protected $pageFactory;
public function __construct(
Context $context,
PageFactory $pageFactory
) {
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
return $this->pageFactory->create();
}
}
Every controller extends Action and implements
execute(), which returns a result (here, a page).
Step 3: Layout File
Define the layout handle for this route in
app/code/Hikmadh/HelloWorld/view/frontend/layout/helloworld_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="Hikmadh\HelloWorld\Block\Index"
name="helloworld_index_index"
template="Hikmadh_HelloWorld::index.phtml" />
</referenceContainer>
</body>
</page>
Step 4: Block Class
Create a simple block in
app/code/Hikmadh/HelloWorld/Block/Index.php:
<?php
namespace Hikmadh\HelloWorld\Block;
use Magento\Framework\View\Element\Template;
class Index extends Template
{
// Add your block methods here if needed
}
Step 5: Template File
Finally, create the template file
app/code/Hikmadh/HelloWorld/view/frontend/templates/index.phtml:
<h2>Welcome to Magento Controller</h2>
Step 6 & 7: Flush Cache and Test
Flush cache:
php bin/magento cache:flush
Then open in your browser:
http://<yourhost.com>/helloworld/index/index
http://<yourhost.com>/helloworld
If everything is set up correctly, you’ll see the “Welcome to Magento Controller” message rendered by your custom controller.