Filament multi-panel setup: admin, vendor and customer
Three Filament 4 panel providers sharing one app, each with its own path, colour, login and discovery folders for resources and pages.
FilamentLayoutsfilamentpanelsmulti-panellaravel
Code
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('admin')
->path('admin')
->login()
->colors(['primary' => Color::Slate])
// Each panel scans its own folder, so resources never leak across panels.
->discoverResources(in: app_path('Filament/Admin/Resources'), for: 'App\\Filament\\Admin\\Resources')
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
->discoverWidgets(in: app_path('Filament/Admin/Widgets'), for: 'App\\Filament\\Admin\\Widgets')
->authMiddleware([Authenticate::class]);
}
}
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
class VendorPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('vendor')
->path('vendor')
->login()
->registration() // vendors can apply for an account
->passwordReset()
->colors(['primary' => Color::Emerald])
->discoverResources(in: app_path('Filament/Vendor/Resources'), for: 'App\\Filament\\Vendor\\Resources')
->discoverPages(in: app_path('Filament/Vendor/Pages'), for: 'App\\Filament\\Vendor\\Pages')
->authMiddleware([Authenticate::class]);
}
}
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Navigation\NavigationItem;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
class CustomerPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('customer')
->path('account')
->login()
->registration()
->emailVerification()
->colors(['primary' => Color::Indigo])
->topNavigation() // a light account area, no sidebar
->navigationItems([
NavigationItem::make('Back to shop')->url('/')->icon('heroicon-o-arrow-left')->sort(100),
])
->discoverResources(in: app_path('Filament/Customer/Resources'), for: 'App\\Filament\\Customer\\Resources')
->discoverPages(in: app_path('Filament/Customer/Pages'), for: 'App\\Filament\\Customer\\Pages')
->authMiddleware([Authenticate::class]);
}
}
Needs: filament/filament@^4.0
How it works
What it solves
Marketplaces, SaaS products and portals have several audiences: staff, sellers and end customers. Putting them all in one Filament panel leads to a maze of permission checks. Separate panels give each audience its own URL, branding, navigation and resource list while sharing models and the database.
How it works
Each PanelProvider returns a Panel with a unique id and path. The important part is discovery: every panel scans a different folder (Filament/Admin, Filament/Vendor, Filament/Customer) and namespace, so a resource only exists in the panel whose folder holds it. Shared code, such as table helpers, lives outside those folders.
The admin panel is login-only, the vendor panel adds registration and password reset for applicants, and the customer panel enables registration and email verification and switches to topNavigation() for a lightweight account area. A NavigationItem adds a link back to the public site.
All three use the same web guard and the same users table. Who may enter which panel is decided by the canAccessPanel() method on the user model (see the role guard snippet).
Adapting it
Rename folders and ids to your audiences. To isolate sessions per panel, give each its own guard with authGuard('vendor') and configure the guard in config/auth.php. Create resources with php artisan make:filament-resource Order --panel=vendor.
Pitfalls
- Register every provider in
bootstrap/providers.php. - Two panels may not share a path, and
/accountmust not clash with an existing route. - Without a role guard, any authenticated user can open any panel.
How to use it
- Install Filament 4:
composer require filament/filament:"^4.0". - Copy the three providers and register them in
bootstrap/providers.php. - Create the discovery folders under
app/Filament/(Admin, Vendor, Customer). - Generate a resource for a panel:
php artisan make:filament-resource Order --panel=vendor. - Add
canAccessPanel()on your user model to decide who can open which panel.
Licence: DEV3 Snippet Licence. Free to use, change and ship in personal and commercial projects. Attribution is appreciated, not required. Please do not redistribute snippets as a collection.