PHPackages                             acerex/filament-menux - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. acerex/filament-menux

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

acerex/filament-menux
=====================

Another menu builder plugin for filament php

v2.2.7(5mo ago)213[4 PRs](https://github.com/Rex-noir/filament-menux/pulls)MITPHPPHP ^8.2CI passing

Since Nov 6Pushed 1mo agoCompare

[ Source](https://github.com/Rex-noir/filament-menux)[ Packagist](https://packagist.org/packages/acerex/filament-menux)[ Docs](https://github.com/Rex-noir/filament-menux)[ GitHub Sponsors](https://github.com/Rex-noir)[ RSS](/packages/acerex-filament-menux/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (6)Dependencies (15)Versions (28)Used By (0)

Good or bad, you decide.
========================

[](#good-or-bad-you-decide)

[![Latest Version on Packagist](https://camo.githubusercontent.com/b51d3c2c8a5bd59733c8a9e3d881df600579845c9e0124ff1f5e3a349bdfa782/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6163657265782f66696c616d656e742d6d656e75782e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/acerex/filament-menux)[![Total Downloads](https://camo.githubusercontent.com/d3a305b1e57daf0f530368db3c4a8a5b207c1c5a760a764f9d4d90d72aa43753/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6163657265782f66696c616d656e742d6d656e75782e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/acerex/filament-menux)

Inspired by existing menu builders, but simplified and easier to customize. Most of the customizations might look trivial, but having to roll your own custom resource and extending the plugin's classes to customize these little things can sometimes become a pain-in-ass (At least in my experience).

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Example Usage](#example-usage)
- [Static Menus](#static-menus)
- [Static Menu Items](#static-menu-items)
- [Using Custom Models](#using-custom-models)
- [Add Model-Based Menu Items](#add-model-based-menu-items)
- [Modifying the Base Resource Class](#modifying-the-base-resource-class)
- [Custom Forms And Tables](#custom-forms-and-table)
- [Action Modifiers](#action-modifiers)
- [Using Custom Link Target Enum](#using-custom-link-target-enum)

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require acerex/filament-menux
```

You can publish and run the migrations with:

```
php artisan vendor:publish --tag="filament-menux-migrations"
php artisan migrate
```

Optionally, you can publish the views using

```
php artisan vendor:publish --tag="filament-menux-views"
```

And also you need to add the plugin as a source in the theme css.

```
@source '../../../../vendor/acerex/filament-menux/resources/views/**/*.blade.php';
```

Example Usage
-------------

[](#example-usage)

To start using, add the plugin to the panel you want.

```
FilamentMenuxPlugin::make()
    ->useStaticMenus([
        'header' => 'Header',
        'footer' => 'Footer',
        ])
    ->addStaticMenuItem('Home', '/')
    ->setNavigationLabel('Custom Menu Label')
    ->setPerPage(4)
    ->setActionModifierUsing(MenuxActionType::EDIT_MENU_ITEM, function (Action $action) {
        return $action->icon(Heroicon::MagnifyingGlassCircle);
    })
    ->addMenuxableModel(Post::class)
    ->setNavigationGroup('Custom Menu Group')
    ->addStaticMenuItem('Contact Us', '/contact-us')
    ->setLinkTargetEnum(linkTargetEnum: LinkTarget::class)
    ->addMenuxableModel(model: Page::class),
```

[![Demo Pic](docs/images/plugin-cover.png)](docs/images/plugin-cover.png)

Registering to panel
--------------------

[](#registering-to-panel)

Just like any other panel plugins, you can register this in your panel provider

```
->plugins([
    \AceREx\FilamentMenux\FilamentMenuxPlugin::make()
])
```

Static Menus
------------

[](#static-menus)

With static menus you can limit how many menus can be created except the menus you provided. This is useful, especially for projects where the frontend fetches the menus statically via slug. To pass static menus, you pass the menus to the **useStaticMenus** method. If you want the plugin to check and create the defined static menus on boot, pass the third second parameter boolean value. By default, it is disabled.

```
\AceREx\FilamentMenux\FilamentMenuxPlugin::make()
    ->useStaticMenus([
        'slug'=>'label',
        'header'=>"Header"
    ], true)
```

Static Menu Items
-----------------

[](#static-menu-items)

Static menu items are shown menu items that you provide from the panel configuration. You can add static menu items like this.

```
->addStaticMenuItem('Home', '/', '_self')
```

The third argument is optional and can also be any type of backed enum. For consistency, you should use the enum you use for the item form. See [Using custom link target enum](#using-custom-link-target-enum)

Grouped Static Menu Items
-------------------------

[](#grouped-static-menu-items)

You can also pass grouped static menu items. For example:

```
->addGroupedMenuItems('Social Medias', [
    [
        'title' => 'Title',
        'url' => 'https://title.com',
        'target' => MenuxLinkTarget::BLANK,
    ],
    [
        'title' => 'Facebook',
        'url' => 'https://www.facebook.com',
        'target' => MenuxLinkTarget::SELF,
    ],
])
```

Or you can pass a function that returns an array. For example:

```
->addGroupedMenuItems('Social Medias', function () {
    return [
        [
            'title' => 'Title',
            'url' => 'https://title.com',
            'target' => MenuxLinkTarget::BLANK,
        ],
        [
            'title' => 'Facebook',
            'url' => 'https://www.facebook.com',
            'target' => MenuxLinkTarget::SELF,
        ],
    ];
})
```

The passed function is deferred till the plugin is fully booted.

[![GroupedMenuItems](docs/images/grouped_menu_items.png)](docs/images/grouped_menu_items.png)

Add Model-Based Menu Items
--------------------------

[](#add-model-based-menu-items)

Inspired by [Menu Builder](https://filamentphp.com/plugins/datlechin-menu-builder) by Ngô Quốc Đạt, this plugin supports registering models and rendering them into menu item list selection.

```
->addMenuxableModel(Post::class)
```

The model must implement interfaces;

```
\AceREx\FilamentMenux\Contracts\Interfaces\Menuxable
```

For example;

```
use Illuminate\Database\Eloquent\Builder;class Post extends Model implements Menuxable
{
    /** @use HasFactory */
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
    ];

    public static function getMenuxLabel(): string
    {
        return 'Posts';
    }

    public function getMenuxTitle(): string
    {
        return $this->title;
    }

    public function getMenuxUrl(): string
    {
        return "https://www.google.com/{$this->slug}";
    }

    public function getMenuxTarget(): BackedEnum
    {
        return MenuxLinkTarget::SELF;
    }

    public static function getMenuxablesUsing(Builder $builder, $page, $perPage, ?string $q): Builder
    {
        if (filled($q)) {
            return $builder->whereLike('title', $q);
        }

        return $builder;
    }

    /**
    * This is optional. You can return an empty collection.
    * This will add a tab for each group so that you don't have to create multiple classes of Model when
    * you only have a single table and want separate tabs for each filtering
    */
    public static function getMenuxableGroups(): Collection
    {
        $collection = collect();
        $collection->put('OnlyDoctors', function (Builder $builder, $page, $perPage, ?string $q) {
            $builder->where('role', 'Doctor');
            if(filled($q)){
                $builder->where('title', 'like', "%{$q}%");
            }
            return $builder;
        });

        return $collection;
    }}
}
```

[![Menuxable Model](docs/images/menuxable-menus-ui-list.png)](docs/images/menuxable-menus-ui-list.png)

#### Set Records Per Page For Menu-Based Menu Items

[](#set-records-per-page-for-menu-based-menu-items)

By default, all menuxable menus are paginated with four records per page. However, you can customize this by providing the number of records you want to query per page via:

```
->setMenuxablesPerPage(4)
```

Using Custom Models
-------------------

[](#using-custom-models)

You can pass your custom models instead of using the default model classes

#### For Custom Menu Model

[](#for-custom-menu-model)

```
->useCustomMenuModel(YourModel::class)
```

Note: Your custom model must extend the plugin's model.

#### For Custom Menu Item Model

[](#for-custom-menu-item-model)

```
->useCustomMenuItemModel(CustomMenuItemModel::class)
```

Note: Your custom model must extend the plugin's model.

Modifying the Base Resource Class
---------------------------------

[](#modifying-the-base-resource-class)

The plugin supports modifying the base resource class without having to extend the base class.

#### Navigation Group

[](#navigation-group)

To Set navigation group of the resource, you can do it like this:

```
->setNavigationGroup('Group')
```

#### Navigation Label

[](#navigation-label)

To Set the navigation label of the resource, you can do it like this:

```
->setNavigationLabel('Label')
```

#### Navigation Icon

[](#navigation-icon)

To set the navigation icon of the resource, you can do it like this:

```
->setNavigationIcon(\Filament\Support\Icons\Heroicon::AcademicCap)
```

Custom Forms and Table
----------------------

[](#custom-forms-and-table)

The plugin also allows you to set custom form and table.

#### Custom Menu Form With Traditional Class

[](#custom-menu-form-with-traditional-class)

```
->setMenuForm(CustomForm::class)
```

The custom form must extend the plugin's `MenuForm` class. For example:

```
use AceREx\FilamentMenux\Filament\Resources\Menus\Schemas\MenuForm as BaseMenuForm;
use Filament\Forms\Components\TextInput;

class MenuForm extends BaseMenuForm
{
    public static function configure(): array
    {
        return [
            TextInput::make('name'),
        ];
    }
}
```

#### Custom Menu Form With Anonymouse Class

[](#custom-menu-form-with-anonymouse-class)

Also, you can pass the anonymouse class

```
->setMenuForm(fn() => new class extends \App\Forms\MenuForm {

    public static function configure(): array
    {
        return [
            Section::make('Menu')
                ->collapsible()
                ->headerActions([
                    DeleteAction::make(),
                    Action::make('save')
                        ->label('Save')
                        ->button()
                        ->action('save'),
                ])
                ->schema([
                    TextInput::make('name')
                        ->label('Name')
                        ->required()
                        ->maxLength(255),
                ]),
        ];
    }

});
```

#### Custom Menus Table

[](#custom-menus-table)

You can also pass custom menus table with both traditional class and function that returns anonymouse class that extends the base MenuTables class, For example.

```
->setMenusTable(\App\Tables\MainMenusTable::class)
```

or

```
->setMenusTable(fn() => new class extends \AceREx\FilamentMenux\Filament\Resources\Menus\Tables\MenusTable {

    public static function configure(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('name')
                    ->label('Name')
                    ->sortable()
                    ->searchable(),
            ])
            ->filters([
                //
            ])
            ->recordActions([
                \Filament\Actions\DeleteAction::make(),
                \Filament\Actions\EditAction::make()
            ])
            ->toolbarActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make(),
                ]),
            ]);
    }

});
```

#### Custom Menu Item Form

[](#custom-menu-item-form)

You can also use your own custom menu item form. Pass your menu item for the class that extends the plugin base class.

```
->setMenuItemForm(YourCustomMenuItemForm::class)
```

You can also pass callable that returns anonymouse class too.

```
->setMenuItemForm(function (){
    return new class Extends \AceREx\FilamentMenux\Filament\Resources\Menus\Schemas\MenuItemForm {
        public function make() : array {
            return [
                \Filament\Forms\Components\TextInput::make('title')
            ];
        }
    }
})
```

To modify the creation of menu items, see the [Action Modifiers](#action-modifiers) section.

Action Modifiers
----------------

[](#action-modifiers)

You can modify actions defined in the `AceREx\FilamentMenux\Contracts\Enums\MenuxActionType`. List of actions modifiable via the panel,

```
enum MenuxActionType: string
{
    /**
     * Used in menu items builder inside the action group.
     */
    case DELETE_MENU_ITEM = 'delete-item';

    /**
     *Used in the menu items builder to delete the selected items.
     */
    case DELETE_SELECTED_MENU_ITEMS = 'delete-selected-items';

    /**
     * Used in menu items builder inside the action group.
     */
    case DUPLICATE__MENU_ITEM = 'duplicate-item';
    /**
     * Used in the menu items builder to edit created menu item.
     */
    case EDIT_MENU_ITEM = 'edit-item';

    /**
     * Used for adding a menu item not defined in the menu tabs.
     */
    case ADD_CUSTOM_MENU_ITEM = 'add-custom-item';

    /**
     * Used for adding a sub menu-item right under the item.
     */
    case CREATE_SUB_MENU_ITEM = 'create-sub-menu-item';
    /**
     * Used for creating the menu from the {@see ListMenus} or the resource header.
     */
    case CREATE_MENU = 'create-menu';
    /**
     * Used inside {@see MenusTable} actions. If you use your own Menus Table,
     * then it might be more practical to modify it inside that custom table.
     */
    case DELETE_MENU = 'delete-menu';
    /**
     * Used inside {@see MenusTable} actions. If you use your own Menus Table,
     * then it might be more practical to modify it inside that custom table.
     */
    case EDIT_MENU = 'edit-menu';
}
```

To modify each action, you pass the action type and return the Action instance. For example, with closure:

```
->setActionModifierUsing(MenuxActionType::DUPLICATE__MENU_ITEM, function (Action $action) {
    return $action
        ->icon(Heroicon::MagnifyingGlassCircle);
```

Here the closure receives the Filament Action instance, and the plugin merges it with the default configurations.

Also, you can pass class-based **Action Modifiers**. For example,

```
use AceREx\FilamentMenux\Contracts\Interfaces\ActionModifier;
use Filament\Actions\Action;

class CustomCreateSubMenuItemAction implements ActionModifier
{
    public function modify(Action $action): Action
    {
        return $action->label('Custom Gigidy');
    }
}
```

and in the panel register the modifier

```
->setActionModifier(MenuxActionType::CREATE_SUB_MENU_ITEM, CustomCreateSubMenuItemAction::class)
```

[![Custom Action Modifier for Sub Menu Item creation](docs/images/action-modifier.png)](docs/images/action-modifier.png)

Using Custom Link Target Enum
-----------------------------

[](#using-custom-link-target-enum)

By default, the plugin uses `MenuxLinkTarget` for model cast and inside menu item form. But sometimes, you would like to show fewer options or modify the labeling. Or add some more functionality. To do that, you can pass your own enum, and that enum will be used inside the menu item form and the model cast.

```
->setLinkTargetEnum(linkTargetEnum: LinkTarget::class)
```

The custom enum must implement two interfaces;

```
\Filament\Actions\Concerns\HasLabel
```

```
\AceREx\FilamentMenux\Contracts\Interfaces\HasStaticDefaultValue
```

For example

```
enum LinkTarget: string implements HasLabel, HasStaticDefaultValue
{
    case SELF = 'self';

    public function getLabel(): string
    {
        return match ($this) {
            self::SELF => 'SELF'
        };
    }

    public static function getStaticDefaultValue(): HasStaticDefaultValue
    {
        return self::SELF;
    }

    public function getSomething(): string
    {
        return 'something';
    }
}
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance82

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 58.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

23

Last Release

178d ago

Major Versions

v1.0.9.1 → v2.0.02025-11-06

### Community

Maintainers

![](https://www.gravatar.com/avatar/68a22d0aaa13a1fdd946a552c141c74cd219a1022182a4d9280ff6e06ec9f578?d=identicon)[acerexnoir](/maintainers/acerexnoir)

---

Top Contributors

[![Rex-noir](https://avatars.githubusercontent.com/u/158605387?v=4)](https://github.com/Rex-noir "Rex-noir (236 commits)")[![awcodes](https://avatars.githubusercontent.com/u/3596800?v=4)](https://github.com/awcodes "awcodes (69 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (30 commits)")[![zepfietje](https://avatars.githubusercontent.com/u/44533235?v=4)](https://github.com/zepfietje "zepfietje (22 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (21 commits)")[![ryangjchandler](https://avatars.githubusercontent.com/u/41837763?v=4)](https://github.com/ryangjchandler "ryangjchandler (7 commits)")[![saade](https://avatars.githubusercontent.com/u/14329460?v=4)](https://github.com/saade "saade (4 commits)")[![maartenpaauw](https://avatars.githubusercontent.com/u/4550875?v=4)](https://github.com/maartenpaauw "maartenpaauw (3 commits)")[![AlexisSerneels](https://avatars.githubusercontent.com/u/287688?v=4)](https://github.com/AlexisSerneels "AlexisSerneels (2 commits)")[![a21ns1g4ts](https://avatars.githubusercontent.com/u/11599205?v=4)](https://github.com/a21ns1g4ts "a21ns1g4ts (1 commits)")[![lucasgiovanny](https://avatars.githubusercontent.com/u/4853801?v=4)](https://github.com/lucasgiovanny "lucasgiovanny (1 commits)")[![rahat1994](https://avatars.githubusercontent.com/u/25553141?v=4)](https://github.com/rahat1994 "rahat1994 (1 commits)")[![Z3d0X](https://avatars.githubusercontent.com/u/75579178?v=4)](https://github.com/Z3d0X "Z3d0X (1 commits)")[![atmonshi](https://avatars.githubusercontent.com/u/1952412?v=4)](https://github.com/atmonshi "atmonshi (1 commits)")[![Abdulmajeed-Jamaan](https://avatars.githubusercontent.com/u/41128358?v=4)](https://github.com/Abdulmajeed-Jamaan "Abdulmajeed-Jamaan (1 commits)")[![cheesegrits](https://avatars.githubusercontent.com/u/934456?v=4)](https://github.com/cheesegrits "cheesegrits (1 commits)")[![darmshot](https://avatars.githubusercontent.com/u/29179227?v=4)](https://github.com/darmshot "darmshot (1 commits)")[![ArielMejiaDev](https://avatars.githubusercontent.com/u/31971074?v=4)](https://github.com/ArielMejiaDev "ArielMejiaDev (1 commits)")

---

Tags

laravel 12filament-v4filament-menu-builderAceRExfilament-menux

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/acerex-filament-menux/health.svg)

```
[![Health](https://phpackages.com/badges/acerex-filament-menux/health.svg)](https://phpackages.com/packages/acerex-filament-menux)
```

###  Alternatives

[datlechin/filament-menu-builder

Create and manage menus and menu items

13550.3k2](/packages/datlechin-filament-menu-builder)[guava/calendar

Adds support for vkurko/calendar to Filament PHP.

298241.0k3](/packages/guava-calendar)[biostate/filament-menu-builder

An Elegant Menu Builder for FilamentPHP

6015.8k](/packages/biostate-filament-menu-builder)[hydrat/filament-table-layout-toggle

Filament plugin adding a toggle button to tables, allowing user to switch between Grid and Table layouts.

6292.3k1](/packages/hydrat-filament-table-layout-toggle)[codewithdennis/filament-lucide-icons

A Filament plugin that integrates Lucide icons, allowing you to use them seamlessly across Filament forms, tables, actions, and more.

4529.4k2](/packages/codewithdennis-filament-lucide-icons)[joaopaulolndev/filament-world-clock

Show hours around the world by timezone

3111.9k](/packages/joaopaulolndev-filament-world-clock)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
