# snowdog/module-menu

> Provides powerful menu editor to replace category based menus in Magento 2

`composer require snowdog/module-menu`

Canonical URL: https://packagento.com/snowdog/module-menu

## At a glance

- **Vendor**: snowdog (https://packagento.com/snowdog.md)
- **Latest version**: 2.29.0 — released 2025-12-01
- **Pricing**: Free
- **Package type**: Magento 2 module
- **Status**: active, accepting new buyers

## Installation

Packagento is licence-gated, so even free packages need a licence on a project before Composer can resolve them.

1. **Sign in or create an account** at https://packagento.com/customer/account/.

2. **Add the package to your account.** Open https://packagento.com/snowdog/module-menu and complete the free checkout. A licence is minted automatically.

3. **Create or pick a project, then activate the licence on it.**
   - Projects represent the Magento installs you deploy to. Manage them at https://packagento.com/projects/.
   - Activate the new licence on the project you'll deploy this package to. Activation is what generates the Composer credentials scoped to that project.

4. **Add the project credentials to your Magento codebase.**

   Grab the project's public + private key from https://packagento.com/projects/ (open the project, then its Credentials tab), and add them to `auth.json`:

   ```json
   {
     "http-basic": {
       "packagento.com": {
         "username": "ppk_live_...",
         "password": "psk_live_..."
       }
     }
   }
   ```

   Add the Packagento Composer repository to `composer.json`:

   ```json
   {
     "repositories": [
       { "type": "composer", "url": "https://packagento.com" }
     ]
   }
   ```

5. **Install and apply.**

   ```bash
   composer require snowdog/module-menu:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

Provides powerful menu editor to replace category based menus in Magento 2

## README

![Static Badge](https://img.shields.io/badge/compatible-compatible?style=for-the-badge&label=Hyv%C3%A4&labelColor=%230A144B&color=%230A23B9%20)
[![Packagist](https://img.shields.io/packagist/v/snowdog/module-menu?style=for-the-badge)](https://packagist.org/packages/snowdog/module-menu)
[![Packagist](https://img.shields.io/packagist/dt/snowdog/module-menu?style=for-the-badge)](https://packagist.org/packages/snowdog/module-menu)
[![Packagist](https://img.shields.io/packagist/dm/snowdog/module-menu?style=for-the-badge)](https://packagist.org/packages/snowdog/module-menu)

**Magento 2 Menu** by [Snowdog](https://snow.dog) is a **powerful menu configurator** that empowers online merchants to create advanced menus, enhancing their customers' shopping experience and improving SEO.
This module serves as a feature-rich replacement for the category-based top navigation found in Magento and Adobe Commerce. However, it offers much more versatility by enabling the creation of menus for various purposes and store views.

**Backend Settings Demo:**

![snowdog-magento-2-menu-admin-configuartio](https://github.com/SnowdogApps/magento2-menu/assets/49198312/102b4d2a-7d06-48a4-9f99-37a17faae0f7)

**Hyvä Demo:**

See our Hyvä top menu mobile, top menu desktop, and footer menu in action: [menu-hyva.snowdog.dev](https://menu-hyva.snowdog.dev/)

### Use Cases
Here are some scenarios where Snowdog's Menu can be effectively used:
* **Create Separate Header Menus for Mobile and Desktop:** Optimize navigation for customers on different devices by creating distinct header menus for mobile and desktop.
* **Create Footer Menu:** Improve the management of footer links.
* **Create Custom Menus for Specific Pages:** Whether you need to add a sidebar menu or change the header menu, Snowdog's module offers you the flexibility to create and customize menus for any page of a Magento store.

### Key Features
* **Flexible Content:** Add various types of elements to menus, such as links, images, and CMS blocks.
* **Product Catalog Integration:** Easily include links to categories and products in menus. Our handy tree selector makes it a breeze to pick the exact categories you want to showcase, or you can opt for category-based import to add a chunk of your catalog tree to the menu with a few clicks.
* **Drag and Drop Editor:** The module offers a user-friendly drag and drop editor, making it effortless to configure multi-level menus exactly how you envision them. Arrange and customize menu items with ease, without any coding knowledge.
* **Import, Export and Duplicate Capabilities:** Save time and effort. This feature enables seamless replication of menus across different instances and Magento stores. It also gives an option to duplicate menus for faster setup and customization.
* **Multiple Ways of Adding Menus to Frontend:** Easily add menus to your frontend using PHTML templates, or fetch the data from our REST and GraphQL APIs. This makes the module very versatile. You can make it work for any Magento frontend.

### User Guide and Documentation
To learn more about Magento 2 Menu by Snowdog, go to [wiki](https://github.com/SnowdogApps/magento2-menu/wiki).

### Magento Versions Compatibility
Menu can be installed on most 2.x Magento versions.
If your Magento version does not work with newest Menu version, see [Contributing](#contributing).

### Contributing
Contributions are welcome! If you find a bug or have a feature request, feel free to open an issue or submit a pull request.

### Like this project?
We'd appreciate it if you leave a ⭐ or share it with the world ✨.

## Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).


### [Unreleased]
#### Added
- Dynamic menu improvements ([#317](https://github.com/SnowdogApps/magento2-menu/discussions/317))
#### Changed
- Long Node cache tag in graphql ([#364](https://github.com/SnowdogApps/magento2-menu/pull/364))
#### Removed
- Frontend console log (SMM-46)
- Unused variables from phtml files ([#357](https://github.com/SnowdogApps/magento2-menu/pull/357))
#### Fixed
- PHP8.4 module compilation errors ([#365](https://github.com/SnowdogApps/magento2-menu/issues/365))
- Database prefix errors ([#368](https://github.com/SnowdogApps/magento2-menu/pull/368))

### [2.28.0] - 2025-03-25
#### Added
- Auto populate node title ([#325](https://github.com/SnowdogApps/magento2-menu/pull/325))
- Add missing $escaper and $viewModels declarations ([#350](https://github.com/SnowdogApps/magento2-menu/pull/350))
- Import categories by store view ([#352](https://github.com/SnowdogApps/magento2-menu/pull/352))
- Add external vue providers config option
#### Changed
- Bump cross-spawn from 7.0.3 to 7.0.6 ([#349](https://github.com/SnowdogApps/magento2-menu/pull/349))
- Improve graphql performance

### [2.27.2] - 2024-11-08
#### Fixed
- Issue when saving nodes w/ db prefix ([#345](https://github.com/SnowdogApps/magento2-menu/pull/345))

### [2.27.1] - 2024-08-07
#### Fixed
- Swagger docs (#332)

### [2.27.0]
#### Added
- `width` and `height` attributes to menu node images (DEV-102271)
- Option to specify customer groups for each node (DEV-94738)
- Snowdog branding in admin panel (DEV-105762)
- Automatically open collapsed menu node when dragging another node inside (DEV-101986)
- Duplicate node functionality (DEV-104364)
#### Fixed
- Impossible to change Cms block, Cms page link after selecting displayed block (DEV-104546)
- Submenu template name issue ([#321](https://github.com/SnowdogApps/magento2-menu/pull/321)) (DEV-105672)
- Issue with 'Import from Categories ([#315](https://github.com/SnowdogApps/magento2-menu/issues/315)) (DEV-105267 & DEV-101741)
#### Updated
- vue-select to 3.20.0 (DEV-104546)

### [2.26.0] - 2024-03-29
#### Fixed
- The function getProductTitle() returns empty string (DEV-104749)
- Hyva error "The element "topmenu_generic" can't have a child" (DEV-104435)
    - Changed custom block names in `default_hyva.xml`:
        - `topmenu.mobile` to `topmenu-mobile`
        - `topmenu.desktop` to `topmenu-desktop`
    - Removed hyva blocks in `default_hyva.xml`:
        - `topmenu.mobile`
        - `topmenu.desktop`

### [2.25.0] - 2024-01-19
#### Added
- 3-level desktop submenu variant (DEV-103924)
#### Fixed
-  category tree import when page url includes index.php (DEV-103904)

### [2.24.1] - 2023-12-05
#### Fixed
- Undefined variable in Hyvä template

### [2.24.0] - 2023-11-28
#### Added
- Hyvä compatibility (DEV-101754)
#### Changed
- Updated eslint version to `8.45.0` and `eslint-plugin-vue` to 9.15.1 (DEV-95002)
#### Fixed
- Mobile nav sidebar (DEV-101802)
- Category Child and CMS block nodes shouldn't have image fields (DEV-94387)
- `custom_url` type node has empty `url_key` in GraphQl context (DEV-103670, [#302](https://github.com/SnowdogApps/magento2-menu/issues/302))
- Added BINARY collation to load menus by identifier (DEV-103752)

### [2.23.1] - 2023-07-28
#### Fixed
- Fixed issue with closing } missing

### [2.23.0] - 2023-07-26
#### Fixed
- Fixed issue about menu block being cached excessively ([#276](https://github.com/SnowdogApps/magento2-menu/issues/276))

#### Changed
- Update GH actions to github-actions-m2 and small code fixes to standards (#100322)
- Don't show <a> tag when there's no url (DEV-100390)

#### Added
- Command to check if menus have invalid nodes and allow removing them through the command (DEV-100331)

_(Changelog truncated for .md surface. Full history on https://packagento.com/snowdog/module-menu.)_

## Recent Versions

| Version | Released |
|---|---|
| 2.29.0 | 2025-12-01 |
| 2.28.0 | 2025-03-25 |
| 2.27.2 | 2024-11-08 |
| 2.27.1 | 2024-08-07 |
| 2.27.0 | 2024-08-05 |
| 2.26.0 | 2024-03-29 |
| 2.25.0 | 2024-01-19 |
| 2.24.1 | 2023-12-05 |
| 2.24.0 | 2023-11-28 |
| 2.23.1 | 2023-08-24 |

Showing 10 of 56 versions. Full release history on https://packagento.com/snowdog/module-menu.

## Dependencies

### Require

| Package | Constraint |
|---|---|
| magento/framework | 100.1.*\|101.0.*\|102.0.*\|103.0.* |
| magento/module-backend | 100.1.*\|100.2.*\|101.0.*\|102.0.* |
| magento/module-catalog | 101.0.*\|102.0.*\|103.0.*\|104.0.* |
| magento/module-cms | 101.0.*\|102.0.*\|103.0.*\|104.0.* |
| magento/module-graph-ql | 100.3.*\|100.4.* |
| magento/module-import-export | 100.3.*\|101.0.* |
| magento/module-media-storage | 100.3.*\|100.4.* |
| symfony/yaml | >=3.2 |

### Require (dev)

| Package | Constraint |
|---|---|
| magento/magento-coding-standard | ^5.0 |

## Quality

Latest release (2.29.0) fails the Packagento QA pipeline. Verdicts below are per-cell (Magento line × PHP version) for the matrixed tools, and run-once for the static / security tiers.


### Compatibility

Each Magento line is installed on its supported PHP versions, then the module is built (DI compile + static-content deploy). Cells show passed / failed / untested; staircase gaps render as `–`.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | Pass | Pass | – | – |
| 2.4.8 | – | Pass | Pass | – |
| 2.4.9 | – | – | 1 | 1 |


### Code Quality

Advisory checks against the module's source. Never affect the Compatibility verdict — a phpcs finding can't make a module incompatible.

#### Static Analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Fail | 254 | 82 errors, 172 warnings (ruleset: Magento2) — 11 auto-fixable with phpcbf |
| PHPMD | Warning | 16 | 16 rule violations (MissingImport:10, UndefinedVariable:5, ExcessiveClassComplexity:1) |
| Cpd | Pass | 0 |  |
| Composer validate | Info | 1 | valid; 1 advisory note (composer validate --strict) |

#### PHPStan

Type-checks the module against a real Magento install. Re-runs per Magento + PHP version because resolvable symbols differ between releases.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | 112 | 112 | – | – |
| 2.4.8 | – | 112 | 112 | – |
| 2.4.9 | – | – | 113 | 113 |


### Tests

Unit and integration suites run per Magento + PHP cell. Test failures speak to the module's behaviour, not its compatibility with a line, so they're reported here separately.

#### Unit Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |

#### Integration Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |


### Security

Dependency-advisory audit (composer audit) plus a source malware scan. A malware detection fails the version outright.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| Composer audit | N/A | 0 | no resolvable dependency tree to audit — Your requirements could not be resolved to an installable set of packages. Problem 1 |
| Malware scan | Pass | 0 |  |

## Licence and pricing

Free. A licence is still minted on checkout and bound to your project for Composer access — no payment step.

Refundable within 14 days of first purchase via https://packagento.com/account/refunds/.

## Install via Claude Code or any MCP client

The Packagento MCP server can run the licence + project + Composer steps above in one tool call:

```
purchase_and_install_packages(
  composer_names=["snowdog/module-menu"],
  project_id="proj_xxx"
)
```

This handles cart, checkout, licence minting, project activation, and writes auth.json credentials. Connect a client with `claude mcp add packagento https://mcp.packagento.com`. Full setup at https://packagento.com/docs/mcp-setup.

## Vendor

snowdog is a Magento 2 vendor on Packagento. See https://packagento.com/snowdog.md for their full catalogue.

