Magento 2 Layout Overview: Layout and Template Customization

Magento 2 Layout Overview: Layout and Template Customization

[Updated: March 06, 2026]

Magento 2 layout customization starts with XML files that control page structure, blocks, and templates. One wrong file name or a missed cache flush can cost hours of debugging.

This tutorial covers the layout system from processing order to working code examples you can use in your custom theme.

Key Takeaways

  • Magento 2 layouts use XML files to control every page element: blocks, containers, templates, and their positions.
  • Layout files follow a strict processing order: base module, area files, collected layouts, theme inheritance, then merge.
  • Blocks hold view logic and connect to .phtml templates. Containers provide HTML structure without logic.
  • Use default.xml for global changes across all pages. Use page-specific XML files like catalog_product_view.xml for targeted changes.
  • Developer mode validates layout XML against XSD schemas. Production mode logs errors without halting.

TL;DR

Magento 2 layout = an XML-based system that defines what appears on every page, where it appears, and how it renders. You control page structure through layout XML files, blocks (PHP logic), and .phtml templates.

Perfect for: Magento developers building custom themes, store owners customizing page structure, agencies extending client stores.

Not ideal for: Non-technical users who need drag-and-drop editing (use Page Builder instead).

What is Magento 2 Layout?

The Magento 2 layout system controls page structure through XML configuration files. Every page in your store, from product pages to checkout, is built from layout instructions that define which blocks appear, where they sit, and which templates render them.

Three core components make up the system:

  1. Layout XML files define page structure (what goes where)
  2. Blocks contain PHP view logic (what data to show)
  3. Templates (.phtml files) render the HTML output (how it looks)

This separation keeps business logic, page structure, and presentation independent. You can move a block from the sidebar to the main content area by changing one XML line, without touching any PHP or template code.

The layout system in Adobe Commerce 2.4.8-p3 (latest stable as of March 2026) follows the same core architecture introduced in Magento 2.0, though theme customization options have expanded with each release. Adobe Commerce 2.4.9 is in alpha (alpha3 since October 2025). The official layout documentation covers the full XML reference.

How Layout Files Are Processed

Layout files follow a strict processing order. Understanding this order prevents conflicts when multiple modules and themes modify the same page.

Processing sequence:

  1. Base module files load first, defining the foundation.
  2. Module area files add frontend or adminhtml specifics.
  3. Collected layouts from all modules load in the sequence defined in app/etc/config.php.
  4. Theme inheritance applies parent-to-child overrides.

If two modules share the same priority, they sort alphabetically. Theme order follows this pattern:

[<parent_theme>, ..., <parent1_theme>] <current_theme>

Starting from the last parent theme to the current theme:

  • Layout files marked as "extend" get added to the merged list.
  • Layout files marked as "override" replace existing entries.
  • All remaining layout files merge into the final page layout.

After merging, Magento validates the result. In developer mode, both syntax and XSD schema validation run. Failures halt the process with an error. In production mode, only syntax validation runs. Schema failures get logged to var/log without throwing exceptions.

magento 2 layout file structure showing global and page-specific changes

Two Methods to Configure Layout Instructions

There are two primary ways to customize the page layout:

Method 1: Modify Layout XML Files

Adjust default.xml for global changes across all pages. Target specific pages by editing page-specific XML files. For example, catalog_product_view.xml controls product pages.

Layout changes in app/code/Vendor/Module/view/frontend/layout/default.xml load on every page. Changes in catalog_product_view.xml affect product detail pages only.

Method 2: Override Templates

Assign different .phtml templates to existing blocks through layout XML. This changes visual output without altering page structure.

Use layout instructions to:

  • Move a page element to a different parent element
  • Add new blocks or containers
  • Remove an existing element from the page
  • Reorder elements within their parent container

customize magento 2 layout for better store structure and page functionality

Layout XML Tags and Their Purpose

The layout XML vocabulary consists of seven core tags. Each serves a distinct purpose in page construction.

Containers

Containers create HTML wrapper elements. They hold blocks and other containers but contain no business logic.

<container name="header.container"
           htmlTag="header"
           htmlClass="page-header"
           htmlId="header">
    <!-- Child blocks and containers go here -->
</container>

Key attributes: name, htmlTag, htmlClass, htmlId, label.

Blocks

Blocks render content through PHP classes and .phtml templates. Each block connects a PHP class (logic) to a template (output).

<block class="Magento\Catalog\Block\Product\View"
       name="product.info.main"
       template="Magento_Catalog::product/view/main.phtml" />

Key attributes: class, name, template, cacheable.

Reference Tags

referenceContainer and referenceBlock modify existing elements without redefining them:

<!-- Add a new block inside an existing container -->
<referenceContainer name="content">
    <block class="Vendor\Module\Block\Custom"
           name="custom.block"
           template="Vendor_Module::custom.phtml" />
</referenceContainer>

<!-- Remove an existing block -->
<referenceBlock name="product.info.sku" remove="true" />

Move

Repositions elements within the layout:

<move element="product.info.price"
      destination="product.info.main"
      after="product.info.title" />

Arguments

Pass data from layout XML to blocks:

<block class="Vendor\Module\Block\Custom" name="custom.block">
    <arguments>
        <argument name="label" xsi:type="string" translate="true">
            Custom Label
        </argument>
    </arguments>
</block>

Update

Include additional layout handles:

<update handle="default_head_blocks" />

default.xml vs. Page-Specific Layout Files

Aspect default.xml Page-Specific XML
Scope All pages in the area Single page type
Use case Headers, footers, navigation, site-wide scripts Product layouts, category grids, checkout steps
Load order First (base configuration) After default.xml (overrides where needed)
File naming default.xml {route_id}_{controller}_{action}.xml
Cache impact Affects full page cache for all pages Cached per page type

Common page-specific layout files:

  • cms_index_index.xml (homepage)
  • catalog_category_view.xml (category pages)
  • catalog_product_view.xml (product pages)
  • checkout_cart_index.xml (cart)
  • checkout_index_index.xml (checkout)
  • customer_account_login.xml (login)

Changes to default.xml require careful testing since they affect every page. Page-specific files can be modified with lower risk. For stores running on managed Magento hosting, proper cache management after layout changes ensures visitors see updates without performance degradation.

How to Create Blocks, Layouts, and Templates: Step by Step

Step 1: Create the Controller

The controller handles the HTTP request and returns the page content.

<?php
namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\View\Result\PageFactory;

class Display implements HttpGetActionInterface
{
    private PageFactory $pageFactory;

    public function __construct(PageFactory $pageFactory)
    {
        $this->pageFactory = $pageFactory;
    }

    public function execute()
    {
        return $this->pageFactory->create();
    }
}

Step 2: Create the Layout XML File

Place your layout file in {module_root}/view/frontend/layout/. The file name follows the pattern {route_id}_{controller}_{action}.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Vendor\Module\Block\Display"
                   name="module.display"
                   template="Vendor_Module::display.phtml" />
        </referenceContainer>
    </body>
</page>

Step 3: Create the Block Class

The block class contains view logic. No HTML or CSS belongs here.

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;

class Display extends Template
{
    public function getGreeting(): string
    {
        return 'Hello World';
    }
}

Step 4: Create the Template File

Create view/frontend/templates/display.phtml:

<?php /** @var \Vendor\Module\Block\Display $block */ ?>
<div class="module-display">
    <h2><?= $block->escapeHtml($block->getGreeting()) ?></h2>
</div>

Step 5: Clear Cache and Test

php bin/magento cache:clean
php bin/magento cache:flush

Navigate to https://your-store.com/module/index/display to verify the output.

For more on cache management, see our guide on clearing Magento cache.

managing magento 2 blocks and containers for page layout adjustments

Blocks in Magento 2: Types and Hierarchy

magento 2 block hierarchy showing structural, content and child blocks

Blocks are the core rendering units in Magento 2. Each block is a PHP object that prepares data and passes it to a .phtml template for HTML output.

Three block types:

  • Structural blocks organize page sections (header, footer, sidebar). They define the page skeleton.
  • Content blocks display products, banners, text, and other visible elements.
  • Child blocks nest inside parent blocks for modular composition.

Blocks support parent-child relationships:

<block class="Vendor\Module\Block\ParentBlock" name="parent_block">
    <block class="Vendor\Module\Block\ChildBlock" name="child_block"
           template="Vendor_Module::child.phtml" />
</block>

The parent block renders its children through $block->getChildHtml('child_block') in its template. This creates a composable, reusable component structure.

Each block can be cached at the individual level. Setting cacheable="false" on a block disables full page cache for the entire page that contains it. Use this with caution on high-traffic Magento stores where full page cache performance matters.

Layout Handle Types

Layout handles determine which XML instructions apply to which pages. Four handle types exist:

Page-type handles correspond to controller action names. The format is {route}_{controller}_{action}. Example: catalog_product_view loads for every product page.

Page layout handles target specific pages with parameters. Example: catalog_product_view_type_simple_id_123 targets only simple product #123.

Arbitrary handles are custom handles you include via <update handle="custom_handle" />. Use them to share layout instructions across multiple pages.

Default handle (default.xml) applies to every page as the base layer.

Layout XML Attributes Reference

Attribute Description Values
name Unique element identifier Letters, numbers, underscore, period, dash. Must start with a letter. Case-sensitive.
template Path to .phtml template Vendor_Module::path/to/template.phtml
class PHP block class Fully qualified class name
htmlTag Container wrapper element div, header, footer, main, aside, section, nav
htmlClass CSS classes for wrapper Any valid CSS class names
before/after Sibling positioning Element name, or - for first/last position
remove Remove element from layout true / false (default)
cacheable Controls block caching true (default) / false
display Element visibility true (default) / false

Common Layout Issues and Solutions

Layout changes not visible: Clear cache with bin/magento cache:clean. Enable developer mode during development for immediate XML validation feedback.

Uncacheable blocks degrading performance: Find blocks with cacheable="false" and isolate them. Use AJAX or ESI (Edge Side Includes) through Varnish to load dynamic blocks without disabling full page cache.

Theme conflicts: Follow the layout override hierarchy. Place customizations in your theme directory (app/design/frontend/Vendor/theme/), not in core module files. Use referenceBlock and referenceContainer instead of copying entire layout files.

Search configuration issues: Adobe Commerce 2.4.8 is optimized for OpenSearch 2.19 and no longer compatible with Elasticsearch. All Elasticsearch 7 and 8 modules are deprecated. For cloud infrastructure, use OpenSearch 3.x (opensearch:3 in .magento/services.yaml). Configure your search engine in Stores > Configuration > Catalog > Catalog Search and verify the layout renders search results through catalogsearch_result_index.xml.

For production environments, proper server configuration prevents most layout rendering issues. A managed hosting setup with Varnish, Redis, and OpenSearch handles the infrastructure side so developers can focus on layout customization.

Creating CMS Blocks in the Admin Panel

CMS blocks let non-developers add content that integrates with the layout system. No code changes required.

  1. Navigate to Content > Elements > Blocks in the admin panel.

magento 2 guide on navigating to blocks and adding a new block

  1. Click Add New Block. Configure these settings:
    • Enable Block: Set to "Yes" (default) or "No" to disable.
    • Block Title: Enter a descriptive title for internal reference.
    • Identifier: Set a unique ID using lowercase characters and underscores.
    • Store View: Select which store views display this block.

magento 2 block general configuration settings overview

  1. Add content using the editor. If Page Builder is enabled, the full drag-and-drop toolset appears.

  2. Click Save & Close.

Reference the CMS block in layout XML:

<referenceContainer name="content">
    <block class="Magento\Cms\Block\Block" name="my.cms.block">
        <arguments>
            <argument name="block_id" xsi:type="string">your_block_identifier</argument>
        </arguments>
    </block>
</referenceContainer>

FAQ

1. What is the difference between a block and a container in Magento 2?

A container creates an HTML wrapper element (like a <div> or <section>) and holds other elements. It has no PHP logic. A block connects a PHP class to a .phtml template and renders content. Containers organize structure. Blocks produce output.

2. Where are layout XML files located in a custom theme?

Custom theme layouts go in app/design/frontend/[Vendor]/[theme]/[Module_Name]/layout/. For example, app/design/frontend/MyVendor/mytheme/Magento_Catalog/layout/catalog_product_view.xml overrides the product page layout.

3. How do I choose between a 2-column and 3-column layout?

A 2-column layout works for product pages where the main content area and one sidebar cover the need. A 3-column layout suits category pages that need filtering options on one side and comparison tools on the other. Set the layout in your XML file: <page layout="2columns-left">.

4. Why are my layout changes not showing on the frontend?

Cache is the most common cause. Run bin/magento cache:clean and bin/magento cache:flush. If that fails, check that your layout file name matches the controller action path. Enable developer mode for detailed XML validation errors.

5. How does layout XML handle theme inheritance?

Child themes inherit all layout files from their parent. To modify a parent layout, create the same file in your child theme directory. Magento merges child theme instructions on top of parent instructions. To replace a layout file entirely, place it in an override subdirectory.

6. What does cacheable="false" do on a block?

Setting cacheable="false" on any block disables full page cache for the entire page containing that block. This affects performance. Use it only when the block content must be unique per request (like a mini cart or customer-specific data). Prefer AJAX loading for dynamic content.

7. How do I add a custom CSS or JS file through layout XML?

Add assets in the <head> section of your layout file:

<page>
    <head>
        <css src="Vendor_Module::css/custom.css" />
        <script src="Vendor_Module::js/custom.js" />
    </head>
</page>

8. Can I use layout XML to modify the admin panel?

Yes. Place layout files in view/adminhtml/layout/ instead of view/frontend/layout/. The same XML tags and structure apply. The admin area uses its own set of layout handles.

9. How do layout changes affect mobile views?

Magento 2 responsive design handles column stacking on smaller screens. Layout changes that add or move blocks work across devices. Test layout modifications on mobile viewports to verify elements stack in the correct order.

10. What is the difference between extending and overriding a layout file?

Extending adds your instructions to the existing layout (merge). Overriding replaces the entire file. Place extending layouts in [theme]/[Module]/layout/. Place overriding layouts in [theme]/[Module]/layout/override/theme/[parent-theme]/. Prefer extending over overriding to maintain compatibility with module updates.

CTA

Summary

The Magento 2 layout system gives developers full control over page structure through XML configuration, PHP block classes, and .phtml templates. Master the processing order, learn the core XML tags, and use default.xml for global changes while targeting specific pages with dedicated layout files.

For production stores where layout performance and cache management matter, managed Magento hosting handles the server infrastructure (Varnish, Redis, OpenSearch) so your layout customizations render fast on every page load.

CEO & Co-Founder

Raphael Thiel co-founded MGT-Commerce in 2011 together with Stefan Wieczorek and has built it into a leading Magento hosting provider serving 5,000+ customers on AWS. With 25+ years in e-commerce and cloud infrastructure, he oversees hosting architecture for enterprise clients. He also co-founded CloudPanel, an open-source server management platform.


Get the fastest Magento Hosting! Get Started