Creating Custom Menu Components
Custom menu components in Hyvä Menu Builder follow the same patterns as standard Hyvä CMS components, with one key addition: you use context_flags to mark components for menu-specific behavior. If you're new to Hyvä CMS components in general, see Creating Components first. This page focuses on the menu-specific parts.
Using the hyva_menu_root Context Flag
To create a root menu component that appears in the menu builder, add the hyva_menu_root context flag. This flag tells the Hyvä CMS editor "this component is a menu", so it shows up when editors create a new menu entity in Menu Builder:
{
"my_mobile_menu": {
"label": "Mobile Menu",
"context_flags": ["hyva_menu_root"],
"children": {
"config": {
"accepts": [
"hyva_menu_item",
"hyva_menu_category_tree",
"hyva_menu_content_container"
],
"max_nesting_level": 6
}
}
}
}
Without the hyva_menu_root context flag, your component won't appear as an option when creating menus. The context_flags property identifies components for specific purposes within the Hyvä CMS editor. In this case, it marks the component as a menu root.
Accepting Children Components
Most menu components need to accept child components for menu content. You control which child components are allowed using the accepts array in your component's children.config section. Typically you'll accept menu items (hyva_menu_item), category trees (hyva_menu_category_tree), content containers (hyva_menu_content_container), or your own custom components:
"children": {
"config": {
"accepts": ["hyva_menu_item", "hyva_menu_category_tree", "hyva_menu_content_container"],
"max_nesting_level": 6
}
}
The max_nesting_level property prevents infinite nesting by limiting how deep the menu structure can go. Without a limit, editors could nest components indefinitely, making the menu hard to manage, slow to load, and difficult to edit. A value of 6 means the menu can be 6 levels deep.
Controlling Child Templates from Parent Components
Parent menu components can control which template renders each child by calling setTemplate() when creating child blocks. This pattern is useful for recursive menu rendering where each level needs to render its children with the same template.
For this to work, the child component must have template set to false and require_parent set to true in its JSON declaration. This tells the system "don't render me with my own template, let my parent decide." Use this pattern when building multi-level menus where templates need to pass state like the current menu level, max_level, or parent_is_category_tree down the tree.
Reference Implementation
The best way to learn is by example. Check out the built-in menu components in module-menu-builder:
hyva_menu_mobile: mobile menu with slide-out drawer.hyva_menu_desktop_drilldown: desktop dropdown menu with hover and click support.hyva_menu_item: basic menu item component.hyva_menu_category_tree: dynamic category tree component.
These show the patterns described on this page in working code.
Related Topics
- Importing Categories: let editors bulk-import catalog categories into your component.
- Category Tree Expander: generate menu items from the live category tree.
- Locking Menus in Preview Mode: keep your component open in the editor preview while it is being edited.
- Rendering Menus in Code: render the finished menu from your theme.