PHPackages                             anish/tenant-menu - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. anish/tenant-menu

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

anish/tenant-menu
=================

Filament plugin for role-based or context-based sidebar navigation using Laravel Auth

v1.0.0(5mo ago)01MITPHPPHP ^8.2

Since Jan 31Pushed 5mo agoCompare

[ Source](https://github.com/anishregmi17/filament-tenant-menu)[ Packagist](https://packagist.org/packages/anish/tenant-menu)[ RSS](/packages/anish-tenant-menu/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

Tenant Menu
===========

[](#tenant-menu)

Role-based or context-based Filament sidebar navigation. Resolve the current context (e.g. user role) with **Laravel Auth**, define groups and items once, and avoid repeating `NavigationItem` boilerplate.

Quick start
-----------

[](#quick-start)

1. **Install** the package: `composer require anish/tenant-menu`
2. **Register** a context resolver and menu definition in a **service provider** (e.g. using `auth()->user()->role`).
3. **Use** the menu in your panel: `->navigation(app(TenantMenu::class)->builder('admin'))`

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

[](#installation)

```
composer require anish/tenant-menu:@dev
```

For a local path package, add the path repository in `composer.json` and run the same command.

Publish config (optional):

```
php artisan vendor:publish --tag=tenant-menu-config
```

Setup
-----

[](#setup)

### 1. Resolve current context (e.g. by role using Auth)

[](#1-resolve-current-context-eg-by-role-using-auth)

In `AppServiceProvider` or a dedicated provider, use Laravel’s `auth()` to return a string key (e.g. role):

```
use Anish\TenantMenu\TenantMenu;

public function boot(): void
{
    $tenantMenu = app(TenantMenu::class);

    $tenantMenu->resolveTenantUsing(function () {
        $user = auth()->user();
        if (! $user) {
            return null;
        }
        // Example: resolve by role (string on User model)
        return $user->role ?? null; // e.g. 'admin', 'manager', 'user'
    });
}
```

Other options:

```
// If your User has a role attribute
return auth()->user()?->role ?? null;

// Or using a method
return auth()->user()?->getRoleKey() ?? null;

// Or using Laravel Gates
return auth()->user() && Gate::allows('access-admin') ? 'admin' : 'user';
```

### 2. Define the menu

[](#2-define-the-menu)

Define the menu for a panel (e.g. `admin`). Use `group(label, icon)` then `->for([...])` to restrict by context keys, and `->add(Resource::class)` or `->add(Page::class)` with optional overrides.

```
use Anish\TenantMenu\TenantMenu;
use App\Filament\Pages\Dashboard;
use App\Filament\Resources\UserResource;
use App\Filament\Resources\PostResource;
use App\Filament\Pages\SettingsPage;
use Filament\Support\Icons\Heroicon;

public function boot(): void
{
    $tenantMenu = app(TenantMenu::class);

    // ... resolveTenantUsing(...) as above ...

    $tenantMenu->define('admin', function ($m) {
        $m->group('')->for(['admin', 'manager', 'user'])
            ->add(Dashboard::class);

        $m->group('Content')->icon(Heroicon::OutlinedDocumentText)->for(['admin', 'manager'])
            ->add(PostResource::class);

        $m->group('Settings')->icon(Heroicon::OutlinedCog6Tooth)->for(['admin'])
            ->add(UserResource::class)
            ->add(SettingsPage::class);

        // Optional overrides: url, visible, isActiveWhen, label
        $m->group('Reports')->for(['admin'])
            ->add(SomeReportPage::class, [
                'url' => fn () => SomeReportPage::getUrl(),
                'visible' => fn () => auth()->user()?->can('view_reports') ?? false,
            ]);
    });
}
```

- **Icon:** pass as the second argument: `$m->group('Settings', Heroicon::OutlinedCog6Tooth)`.
- **`->for(['admin'])`:** only users whose resolver returns `'admin'` see that group.
- **Overrides:** `url`, `visible`, `isActiveWhen`, `label` (closure or string).

### 3. Use in the panel

[](#3-use-in-the-panel)

In your panel provider (e.g. `AdminPanelProvider`):

```
use Anish\TenantMenu\TenantMenu;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->navigation(app(TenantMenu::class)->builder('admin'))
        // ...
}
```

Or with the plugin:

```
use Anish\TenantMenu\TenantMenuPlugin;

$panel
    ->plugins([TenantMenuPlugin::make(), /* ... */])
    ->navigation(TenantMenuPlugin::make()->navigationBuilder('admin'));
```

Minimal example
---------------

[](#minimal-example)

One provider that wires everything:

```
// e.g. app/Providers/TenantMenuRegistrationServiceProvider.php
use Anish\TenantMenu\TenantMenu;
use App\Filament\Pages\Dashboard;
use Filament\Panel;

public function boot(): void
{
    $menu = app(TenantMenu::class);

    $menu->resolveTenantUsing(fn () => auth()->user()?->role ?? null);

    $menu->define('admin', function ($m) {
        $m->group('')->for(['admin', 'user'])->add(Dashboard::class);
    });
}
```

Panel:

```
->navigation(app(TenantMenu::class)->builder('admin'))
```

Overrides
---------

[](#overrides)

When adding a Resource, Page, or Cluster you can pass overrides as the second argument to `add()`:

KeyTypeExample`url``Closure|string``fn () => SomeResource::getUrl('page')``visible``Closure|bool``fn () => auth()->user()?->can('view')``isActiveWhen``Closure``fn () => request()->routeIs('...')``label``string|Closure``'Custom Label'`API
---

[](#api)

- **`resolveTenantUsing(\Closure $resolver)`**
    Set a closure that returns the current context key (e.g. `'admin'`, `'manager'`) or `null`. Use Laravel Auth inside the closure.
- **`define(string $panelId, \Closure $callback)`**
    Define the menu for a panel. The closure receives one argument `$m` (MenuDefinition).
- **`builder(string $panelId)`**
    Returns a closure suitable for `Panel::navigation()`.
- **`$m->group(string $label, $icon = null)`**
    Starts a navigation group. Then:

    - **`->for(array $keys)`** – context keys that can see this group (e.g. `['admin', 'manager']`).
    - **`->add(string $class, array $overrides = [])`** – add a Resource, Page, or Cluster; optional `url`, `visible`, `isActiveWhen`, `label`.
    - **`->addItem(NavigationItem $item)`** – add a raw Filament NavigationItem.
    - **`->collapsible(bool)`**, **`->collapsed(bool)`**

If a group has no `->for()`, it is visible for any context (including when the resolver returns `null`).

License
-------

[](#license)

MIT.

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance73

Regular maintenance activity

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

152d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/103883548?v=4)[Anish Regmi ](/maintainers/anishregmi17)[@anishregmi17](https://github.com/anishregmi17)

---

Top Contributors

[![anishregmi17](https://avatars.githubusercontent.com/u/103883548?v=4)](https://github.com/anishregmi17 "anishregmi17 (2 commits)")

### Embed Badge

![Health badge](/badges/anish-tenant-menu/health.svg)

```
[![Health](https://phpackages.com/badges/anish-tenant-menu/health.svg)](https://phpackages.com/packages/anish-tenant-menu)
```

###  Alternatives

[althinect/filament-spatie-roles-permissions

3481.1M10](/packages/althinect-filament-spatie-roles-permissions)[directorytree/ldaprecord-laravel

LDAP Authentication &amp; Management for Laravel.

5752.3M18](/packages/directorytree-ldaprecord-laravel)[illuminate/auth

The Illuminate Auth package.

10528.2M1.2k](/packages/illuminate-auth)[stephenjude/filament-two-factor-authentication

Filament Two Factor Authentication: Google 2FA + Passkey Authentication

84215.9k9](/packages/stephenjude-filament-two-factor-authentication)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.6k](/packages/rawilk-profile-filament-plugin)[marcelweidum/filament-passkeys

Use passkeys in your filamentphp app

6649.5k1](/packages/marcelweidum-filament-passkeys)

PHPackages © 2026

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