Hyvä code in a -hyva module
Hyvä storefront code in its own -hyva module, next to your Light glue.
Light is not tied to Hyvä: Light core ships the Luma storefront code of its modules, and every Hyvä part sits in a separate module per core module. A module of yours with Light parts and Hyvä parts splits the same way. This recipe walks through Mrx_ContentHyva, which puts the menu editor's links and the footer menu on a Hyvä storefront.
When to use it
- Your module has Light parts and a Hyvä storefront part: templates, layout on
hyva_*handles, Tailwind classes, plugins on Hyvä classes. - Admin handling of a Hyvä package too, such as hiding a Hyvä module on the Apps page (An app, its category and pins).
- Keep your Light glue free of Hyvä, so shops without Hyvä never load it (Built for Light, rule 2).
Steps
Mrx_ContentHyva in full:
1. Name and package
<Vendor>_<Module>Hyva next to its base module, in the package <vendor>/module-<module>-hyva. Light's are Mrx_ContentHyva (mrx/module-content-hyva), Mrx_SettingsHyva and Mrx_DiscountsHyva.
2. Register it as a compat module
It registers in Hyvä's CompatModuleRegistry with its base module as original_module, so on a Hyvä theme its templates override the base module's at the same path:
<item name="mrx_content_hyva" xsi:type="array">
<item name="original_module" xsi:type="string">Mrx_Content</item>
<item name="compat_module" xsi:type="string">Mrx_ContentHyva</item>
</item>It sequences its base module, Hyva_Theme and Hyva_CompatModuleFallback:
<module name="Mrx_Content"/>
<module name="Hyva_Theme"/>
<module name="Hyva_CompatModuleFallback"/>3. Layout on hyva_* handles
Its layout lives on hyva_* handles, which only load on a Hyvä theme:
<referenceBlock name="footer-static-links" remove="true"/>
<referenceBlock name="footer-content">
<block class="Mrx\Content\Block\FooterMenu" name="mrx.content.footer.menu" template="Mrx_ContentHyva::footer-menu.phtml" before="-"/>
</referenceBlock>A Luma block your base module puts in a block Hyvä doesn't have (here footer_links) is declared again on hyva_default, under the same name, in a Hyvä block. hyva_default loads after default, so the block moves before Magento builds the page and developer mode logs no "Broken reference" line. A remove="true" doesn't do that: Magento removes elements only after it placed them, and logs the missing parent first.
Plugins on Hyvä classes go in its etc/frontend/di.xml, and it may call the internal classes of its one base module, because both ship in the same release. Any other Light class it names must be @api, or the doctor reports private_api.
4. The Tailwind build
app/etc/hyva-themes.json lists the module, so the Hyvä Tailwind build scans its templates and its view/frontend/tailwind/module.css. After enabling a new -hyva module:
bin/magento hyva:config:generateThen run the Tailwind build of your Hyvä theme.
5. The range and the range guard
A -hyva module is not core: it declares extra.mrx-light-api in its own composer.json, and its PHP names Light classes of its base module, so its registration.php carries the range guard:
if (class_exists(\Mrx\Light\Api\ExtensionApi::class) && \Mrx\Light\Api\ExtensionApi::satisfies('^0.4')) {6. What the base module keeps
The base module keeps its Luma storefront code and may offer a generic hook that a theme's compat module calls, as long as it names no Hyvä type. Light core never names Hyva\ or Hyva_, has no hyva_* layout and no view/frontend/tailwind/ folder; the doctor rule hyva_in_core fails otherwise.
What the admin sees
Nothing changes in the admin. On a Hyvä store view, the storefront shows the module's Hyvä templates; on Luma, the base module's.
ACL
None: storefront code.
Check it
bin/magento mrx:light:doctor:hyva_in_corefor Hyvä code in core,api_constraintfor a missing guard.bin/magento module:status Mrx_ContentHyvashows it enabled.- Open a Hyvä store view and check the storefront part.
Pitfalls
- A change that doesn't show on the storefront: the
-hyvamodule is disabled, its range guard left it unregistered, orhyva-themes.jsondoesn't list it (Troubleshooting). - A
-hyvamodule may be disabled; core modules may not.
Last updated on