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.