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:flushThen open in your browser:
http://<yourhost.com>/helloworld/index/index
http://<yourhost.com>/helloworldIf everything is set up correctly, you’ll see the “Welcome to Magento Controller” message rendered by your custom controller.