What is a Route in Magento 2?
The Routing Pipeline
Every HTTP request entering Magento 2 goes through a routing pipeline. The router reads routes.xml files from all active modules, matches the URL's front name to a route definition, and dispatches the request to the appropriate controller action.
The flow is:
HTTP Request → Bootstrap → Router → Route Match → Controller → Action → Response
Route Configuration Locations
Routes are defined in etc/ directories under the module namespace:
frontend/etc/routes.xml— frontend store routesadminhtml/etc/routes.xml— admin panel routes
Each area has its own routing scope. A module can define routes for frontend, adminhtml, or both.
Basic routes.xml Structure
<?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="catalog" frontName="catalog">
<module name="Magento_Catalog"/>
</route>
</router>
</config>
Key attributes:
- router id — always
standardfor frontend routes - route id — unique identifier for this route (typically lowercase module name)
- frontName — the URL prefix that maps to this route (e.g.,
catalog/product/view) - module name — the module that owns this route, in
Vendor_Moduleformat
How Magento Matches a URL
When a user visits catalog/product/view/id/1:
- The router extracts the first path segment:
catalog - It looks up which route has
frontName="catalog" - It finds
Magento_Catalogmodule owns this route - It constructs the controller class:
Magento\Catalog\Controller\Product\View - It instantiates the controller and calls
execute()
The front name determines the first segment of the URL. Everything after that maps to the Controller directory structure.
Frontend Routes Configuration
Frontend Route Definition
Frontend routes live in Vendor/Module/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="wishlist" frontName="wishlist">
<module name="Magento_Wishlist"/>
</route>
</router>
</config>
The router id="standard" is required for frontend routes. This tells Magento to use the standard URL router, not a custom one.
Route ID vs Front Name
The id and frontName can differ, but convention is to keep them identical:
<!-- Convention: id and frontName match -->
<route id="blog" frontName="blog">
<module name="Vendor_Blog"/>
</route>
<!-- Allowed but discouraged: different id and frontName -->
<route id="my_module_route" frontName="my-path">
<module name="Vendor_MyModule"/>
</route>
The id is used internally by Magento for route matching and dependency resolution. The frontName is what appears in the URL.
Multiple Modules Per Route
Sometimes two modules share a route. The second module extends the first:
<route id="customer" frontName="customer">
<module name="Magento_Customer"/>
</route>
<!-- In another module's routes.xml -->
<route id="customer" frontName="customer">
<module name="Magento_Quote"/>
</route>
When multiple modules claim the same route, Magento loads controllers from all modules. If Magento_Customer has Account/LoginAction and Magento_Quote also has Account/LoginAction, the last-loaded module wins.
Module Load Order
Route priority depends on module load order defined in app/etc/config.php. Modules listed later in the modules array load after earlier ones, giving their routes priority during conflict resolution.
You can check module order with:
bin/magento module:status
bin/magento setup:module-dependencies-report
Adminhtml Routes
Admin Route Definition
Admin routes use a different router and live in Vendor/Module/etc/adminhtml/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="admin">
<route id="admin" frontName="admin">
<module name="Magento_Backend"/>
</route>
</router>
</config>
Notice router id="admin" instead of standard. The admin router handles authentication, ACL checks, and menu rendering.
Custom Admin Routes
Third-party modules define their own admin routes under the admin router:
<?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="admin">
<route id="vendor_shipping" frontName="vendor_shipping">
<module name="Vendor_Shipping"/>
</route>
</router>
</config>
This creates URLs like admin/vendor_shipping/... where admin is the admin front name and vendor_shipping is your module's front name.
Admin URL Structure
Admin URLs follow the pattern:
{admin_path}/{module_frontName}/{controller}/{action}
For example, admin/catalog/product/edit/id/1 maps to:
admin→ admin routercatalog→ route frontNameproduct→ Controller directoryedit→ EditAction classid/1→ request parameters
Restricting Admin Routes
Admin routes should be protected by ACL resources defined in etc/acl.xml. The admin router checks the current user's permissions before dispatching to the controller.
<!-- etc/acl.xml -->
<config>
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Magento_Backend::stores">
<resource id="Vendor_Shipping::config" title="Vendor Shipping Config"/>
</resource>
</resource>
</resources>
</acl>
</config>
URL to Controller Mapping Examples
Complete URL Mapping Walkthrough
Let's trace a complete request through the routing system.
Example 1: Product View Page
URL: catalog/product/view/id/123/some-product
- Router finds
catalogfrontName →Magento_Catalogmodule - Controller path:
Controller/Product/View.php - Action class:
Magento\Catalog\Controller\Product\View - Request params:
id=123,some-product(last segment ignored or used as slug)
namespace Magento\Catalog\Controller\Product;
use Magento\Framework\App\Action\HttpGetActionInterface;
class View implements HttpGetActionInterface
{
public function execute()
{
// Request param access
$productId = $this->getRequest()->getParam('id');
// ... load product, return result
}
}
Example 2: Customer Account
URL: customer/account/loginPost
- Router finds
customerfrontName →Magento_Customermodule - Controller path:
Controller/Account/LoginPost.php - Action class:
Magento\Customer\Controller\Account\LoginPost
namespace Magento\Customer\Controller\Account;
use Magento\Framework\App\Action\HttpPostActionInterface;
class LoginPost implements HttpPostActionInterface
{
public function execute()
{
// Handle login POST
}
}
Example 3: Nested Controller Path
URL: blog/post/view/id/5
If your module has a deeper controller path, the URL segments map directly:
blog → route frontName
post → Controller/Post/ directory
view → ViewAction.php
id/5 → request parameter
Controller file: Vendor/Blog/Controller/Post/View.php
Route Debugging Tips
Enable route debugging by adding to app/etc/env.php:
'system' => [
'debug' => [
'log_router_enabled' => true,
],
]
This logs all route matches to var/log/system.log, showing which routes were tried and which matched.
Another approach: check compiled routes:
bin/magento setup:di:compile
cat var/di/development.log # Shows route configurations
Quiz
1. What attribute in routes.xml determines the URL prefix for a route?
2. Which router id should be used for frontend routes?
3. Given the URL 'catalog/product/view/id/123', what is the controller action class path?
Flashcards
Question
What does frontName control in routes.xml?
Click to reveal answer
Answer
The URL prefix that maps to the route. It is the first segment of the URL path.
Question
What router id is used for frontend routes?
Click to reveal answer
Answer
standard
Question
What router id is used for admin routes?
Click to reveal answer
Answer
admin
Question
Where do frontend routes.xml files live in a module?
Click to reveal answer
Answer
Vendor/Module/etc/frontend/routes.xml
Question
How does Magento map 'catalog/product/view' to a controller?
Click to reveal answer
Answer
Router matches 'catalog' to the route, then 'product/view' maps to Controller/Product/View.php
Revision Notes
Key Takeaways
- 1. routes.xml maps front names to modules via the router
- 2. Frontend routes use router id='standard', admin routes use router id='admin'
- 3. frontName is the URL prefix; id is the internal route identifier
- 4. URL segments after the frontName map to Controller directory structure
- 5. Multiple modules can share a route ID for module merging
Interview Tips
- • Explain the full flow from HTTP request to controller dispatch
- • Know the difference between route id and frontName
- • Be ready to discuss how multiple modules can extend the same route
- • Debug routing issues by checking route compilation and log_router_enabled
Cheat Sheet
Frontend route:
<route id="mymod" frontName="mymod">
<module name="Vendor_MyModule"/>
</route>
Admin route:
<router id="admin">
<route id="admin" frontName="admin">
<module name="Magento_Backend"/>
</route>
</router>
URL → Controller:
mymod/something/do → Controller/Something/Do.php