Headless Components for Magento 2
neutromelabs/magento2-headless-components
Renders phtml-based templates without registering them in layout XML, with native theme overrides, block caching, FPC compatibility, and first-class AlpineJS companion blocks for building modular components.
Build Tests
Code Quality
Tested on Magento 2.4.9
Recent Test History
Each release is tested against the latest Magento version at that time.
Top Contributors
View LeaderboardShare This Module's Status
README
Loaded from GitHubUncomplicate rich modular layouts based on AlpineJS-components
with Magento 2 Headless Components experience.
Magento 2 Headless Components Module
Provides a simple way to render phtml-based templates, without the need to register them in the xml layout. Includes caching, native Magento theme overrides, and first-class AlpineJS support.
Overview
This is a tool to do a
\Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\View\LayoutInterface::class)
->createBlock(\Magento\Framework\View\Element\Template::class)
->setTemplate('Vendor_Module::component/headless/block/template.phtml')
->toHtml();
in a "better" way:
- Native Magento theme overrides
- Block caching
- FPC compatible
- JS-companion blocks for AlpineJS
The Problem
- Magento 2 has no ability to simply render templates like
{{ templates/button }}as almost every other templating engine provides. - AlpineJS-based themes and components become hard to upgrade when overwritten, because of the need to copy-paste the whole JS logic within the template.
Proposed Solution
This module provides an easier way to render templates, with first-class AlpineJS support
via decoupling JS logic from templates into .script.phtml companion files.
The layout system is used for macro-level layouting (header, footer, product-details),
and Headless Components for atom/block level - button, input, accordion.
Installation
composer require neutromelabs/magento2-headless-components
bin/magento setup:upgrade
How To Use
Basic Usage
/** view/frontend/templates/some/template.phtml */
<?= $block->headlessComponentRenderer->render('atom/input-text', [
'type' => 'email',
'name' => 'email',
'label' => __('Email'),
'attributes' => [
'required' => 1,
'value' => $address->getEmail(),
'x-model' => 'displayEmail',
'@change' => 'await save()'
]
], 'address-form.input-email') ?>
Configuration
Configure the component module via DI:
<!-- di.xml -->
<type name="NeutromeLabs\HeadlessComponents\Service\Renderer">
<arguments>
<argument name="componentModule" xsi:type="string">Vendor_MyComponents</argument>
</arguments>
</type>
Then create your templates:
Vendor/MyComponents/view/frontend/templates/atom/input-text.phtml
Vendor/MyComponents/view/frontend/templates/atom/input-text.script.phtml <!-- AlpineJS companion -->
Overriding Components
Use standard Magento theme overrides:
app/design/frontend/Vendor/theme/Vendor_MyComponents/templates/atom/input-text.phtml
Script Companions (AlpineJS)
For any template foo/bar.phtml, create foo/bar.script.phtml for the JS logic.
The script companion is automatically detected and rendered once per page in before.body.end.
<!-- atom/button.phtml -->
<button x-data="myButton()" @click="handleClick">
<span x-text="label"></span>
</button>
<!-- atom/button.script.phtml -->
<script>
function myButton() {
return {
label: 'Click me',
handleClick() {
console.log('clicked');
}
}
}
</script>
This content is fetched directly from the module's GitHub repository. We are not the authors of this content and take no responsibility for its accuracy, completeness, or any consequences arising from its use.