Adding a Filament Panel
The starter ships with a single Filament panel — the Administration panel at /administration — for back-end staff tooling. However, many applications need more than just an admin area. If your application involves CRUD tables, data exports, filterable lists, info displays, or action-driven workflows, creating a separate Filament panel is often the most productive path.
When to Use a Separate Panel
Section titled “When to Use a Separate Panel”The Bootstrap-based user-facing stack (Blade + Northwestern Laravel UI) is the right choice for public landing pages, branded content, and heavily custom interfaces. But for authenticated, data-driven experiences — especially those involving tables, forms, filters, and bulk actions — Filament’s component library can save significant development time.
Common use cases for a second panel:
- Student or applicant portals — review status, upload documents, view decisions
- Faculty/staff dashboards — manage courses, events, or departmental data
- Reviewer or coordinator tools — evaluate submissions, assign reviewers, track progress
- Self-service data management — any authenticated user managing their own records
Creating a New Panel
Section titled “Creating a New Panel”-
Generate the panel provider
Terminal window php artisan make:filament-panel portalThis creates a new provider at
app/Providers/Filament/PortalPanelProvider.phpand registers it automatically. -
Define a panel ID constant
Follow the pattern established by
AdministrationPanelProvider— define a publicIDconstant and reference it consistently:app/Providers/Filament/PortalPanelProvider.php class PortalPanelProvider extends PanelProvider{public const string ID = 'portal';public function panel(Panel $panel): Panel{return $panel->id(self::ID)->path(self::ID)// ...}} -
Configure the middleware stack
Your new panel needs the same middleware foundation as the Administration panel. At minimum, include the
InjectLivewireAssetsmiddleware — it resolves a conflict between the Bootstrap stack’s bundled Livewire assets and Filament’s asset injection:->middleware([InjectLivewireAssets::class,EncryptCookies::class,AddQueuedCookiesToResponse::class,StartSession::class,ShareErrorsFromSession::class,VerifyCsrfToken::class,SubstituteBindings::class,DisableBladeIconComponents::class,DispatchServingFilamentEvent::class,])->authMiddleware([Authenticate::class,]) -
Configure SPA mode
SPA mode gives Filament a single-page-app feel with client-side navigation. If you enable it, exclude the authentication and impersonation routes so full page loads occur for those flows:
->spa()->spaUrlExceptions([url('/auth/*'),url('/impersonate/*'),]) -
Set up resource discovery
Create a dedicated directory for your panel’s resources and point the panel at it. This keeps resources cleanly separated from the Administration panel:
->discoverResources(in: app_path('Filament/Portal/Resources'), for: 'App\Filament\Portal\Resources')->discoverPages(in: app_path('Filament/Portal/Pages'), for: 'App\Filament\Portal\Pages')->discoverWidgets(in: app_path('Filament/Portal/Widgets'), for: 'App\Filament\Portal\Widgets') -
Add optional features
Consider which features from the Administration panel you want to carry over:
->colors(['primary' => Color::Purple])->favicon('https://common.northwestern.edu/v8/icons/favicon-32.png')->brandLogo(config('northwestern-theme.lockup'))->databaseNotifications()->databaseNotificationsPolling('30s')->globalSearch()->globalSearchDebounce('500ms')->plugins([EnvironmentIndicatorPlugin::make()->visible(! app()->isProduction())->color(Color::Yellow),])
Gating Access
Section titled “Gating Access”Update canAccessPanel()
Section titled “Update canAccessPanel()”The User::canAccessPanel() method uses a match statement that intentionally throws an exception for unrecognized panel IDs. You must add your new panel here:
return match ($panel->getId()) { AdministrationPanelProvider::ID => $this->can(SystemPermission::AccessAdministrationPanel), PortalPanelProvider::ID => $this->can(SystemPermission::AccessPortal),};Add a new permission
Section titled “Add a new permission”Define a new permission in SystemPermission for your panel:
case AccessPortal = 'access-portal';Then add a description, set the system-managed flag, and configure the scope — following the patterns of the existing AccessAdministrationPanel permission.
Navigation Groups
Section titled “Navigation Groups”The Administration panel organizes its sidebar with a HasLabel enum. Create an equivalent for your new panel:
namespace App\Filament\Portal\Navigation;
use Filament\Support\Contracts\HasLabel;
enum PortalNavGroup implements HasLabel{ case Dashboard; case MyRecords;
public function getLabel(): string { return match ($this) { self::Dashboard => 'Dashboard', self::MyRecords => 'My Records', }; }}Then reference it in your resources:
protected static string|null|UnitEnum $navigationGroup = PortalNavGroup::MyRecords;protected static ?int $navigationSort = 1;Generating Resources
Section titled “Generating Resources”When generating resources for your new panel, specify both the model namespace and the panel:
php artisan make:filament-resource Application \ --generate \ --model-namespace=App\\Domains\\Application\\Models \ --panel=portalThe --panel flag ensures the resource is placed in the correct directory for your panel’s discovery path.
Architecture Patterns to Follow
Section titled “Architecture Patterns to Follow”The Administration panel establishes several patterns worth replicating:
| Pattern | What to do | Reference |
|---|---|---|
| Panel ID constant | Define public const string ID on the provider | AdministrationPanelProvider::ID |
| Permission gating | One permission per panel in SystemPermission | AccessAdministrationPanel |
| Nav group enum | A HasLabel enum per panel for sidebar organization | AdministrationNavGroup |
| Heroicon constants | Use the Heroicon enum instead of raw strings | Heroicon::OutlinedUsers |
| Resource separation | Dedicated directories per panel under app/Filament/ | app/Filament/Resources/ |
| Policies | Standard Laravel policies — Filament respects them automatically | UserPolicy, RolePolicy |