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(3mo ago)01MITPHPPHP ^8.2

Since Jan 31Pushed 3mo 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 1mo ago

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

35

—

LowBetter than 79% of packages

Maintenance80

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

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

106d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/aa00f496111071417a1607e92ce7d5b1297cadf3c255dd7fb9af32b9187b30ac?d=identicon)[anishregmi17](/maintainers/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

[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[althinect/filament-spatie-roles-permissions

340954.7k9](/packages/althinect-filament-spatie-roles-permissions)[andrewdwallo/filament-companies

A comprehensive Laravel authentication and authorization system designed for Filament, focusing on multi-tenant company management.

34450.0k2](/packages/andrewdwallo-filament-companies)[illuminate/auth

The Illuminate Auth package.

9327.3M1.0k](/packages/illuminate-auth)[olssonm/l5-very-basic-auth

Laravel stateless HTTP basic auth without the need for a database

1662.5M1](/packages/olssonm-l5-very-basic-auth)[scaler-tech/laravel-saml2

SAML2 Service Provider integration for Laravel applications, based on OneLogin toolkit

2737.5k](/packages/scaler-tech-laravel-saml2)

PHPackages © 2026

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