rewi.sh / menu
Menus, navigation, and navbar builder for Craft CMS — nested nav, element links, Twig, and GraphQL.
1.1.2
2026-11-03 14:51 UTC
Requires
- php: >=8.2
- craftcms/cms: ^5.0.0 || ^6.0
Requires (Dev)
- php-cs-fixer/shim: ^3.85
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Nested site menus for Craft CMS. Built by rewi.sh.
Package rewi.sh/menu. Handle menu. Craft 5.0+ / 6.0+. PHP 8.2+.
Control panel translations: en, de, fr, it, nl.
Install
composer require rewi.sh/menu -w && php craft plugin/install menu
DDEV:
ddev composer require rewi.sh/menu -w && ddev craft plugin/install menu
Update
composer update rewi.sh/menu -w && php craft migrate/all
DDEV: ddev composer update rewi.sh/menu -w && ddev craft migrate/all
What you get
- CP section Menu — create menus and drag-drop nested nodes
- Node types: custom URL, entry, category, asset, product (Commerce), passive, site, anchor, separator, dynamic (section / category group / asset volume / product type → projected children, ordered by title or date)
- Per-node visibility rules, missing-element fallback, link health, badges, icons, mega-menu and mobile options
- Duplicate menus and nodes, bulk enable / disable / delete, live filter, CP preview
- Menu field type,
craft.menu.render()accessible nav macro, optional token-protected JSON API - Per-menu sites, node field layouts, and manage permissions
- CSS classes, URL suffix, custom attributes, new window
- Twig:
craft.menu.tree(),activeTree(),breadcrumbs(),isActive/isCurrent - GraphQL:
menu,menus,menuNodes(withchildren,active,current,projected),menuBreadcrumbs - Export / import menu JSON from the node builder
- Migrate from Verbb under Settings (and via console)
- Docs in
docs/
Twig
{% set tree = craft.menu.activeTree('main') %}
<ul>
{% for item in tree %}
<li class="{{ item.active ? 'is-active' }}{{ item.current ? ' is-current' }}">
{% if item.node.nodeUrl %}
<a href="{{ item.node.nodeUrl }}"{% if item.node.newWindow %} target="_blank" rel="noopener"{% endif %}>
{{ item.node.title }}
</a>
{% else %}
<span>{{ item.node.title }}</span>
{% endif %}
{# item.children is the same shape #}
</li>
{% endfor %}
</ul>
{% set crumbs = craft.menu.breadcrumbs('main') %}
GraphQL
{
menu(handle: "main") { id title handle }
menuNodes(handle: "main", level: 1) {
id title url active(uri: "about/team") current(uri: "about/team")
children { id title url }
}
menuBreadcrumbs(handle: "main", uri: "about/team") { id title url }
}
Migrate from Verbb
Reads navigation_menus / navigation_nodes and creates Menu elements. Existing handles are skipped. Entry / category / asset / custom (and passive/group/site → custom) are imported; Product and Dynamic nodes are skipped.
php craft menu/migrate/navigation --dry-run=1 php craft menu/migrate/navigation --dry-run=0
Or use Menu → Settings → Migrate from Verbb Navigation in the control panel.
License
MIT.