# SECTION A — FILAMENT V5 NOTES (BULLETS + SOURCES)

> **Status:** Active  
> **Last reviewed:** 2026-04-30  
> **Use for:** Filament v5 reference notes and framework-specific decision checks when local behavior is uncertain  
> **Do not use for:** Assuming local implementation already follows every note without repo verification

## Versioning & Base Requirements
- Rule: Filament v5 requires Livewire v4.0+.
  When: Always when installing/upgrading Filament v5. When NOT: Never target Livewire v3 in a v5 codebase.
  Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire”

## Panels — Configuration
- Rule: Panels are configured via dedicated panel providers; the default admin panel ships at `/admin`.
  When: Always—centralize panel setup (resources/pages/widgets/plugins) here. When NOT: Don’t scatter core panel configuration across unrelated providers.
  Source: https://filamentphp.com/docs/5.x/panel-configuration — “The default admin panel”
- Rule: New panel providers must be registered in `bootstrap/providers.php` for Laravel 11+ (or `config/app.php` for Laravel 10 and below).
  When: When adding a new panel or if panel creation didn’t auto-register. When NOT: Don’t register panel providers in `bootstrap/app.php`.
  Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel”
- Rule: Use `path()` to change a panel’s URL prefix; `path('')` mounts at `/` and can conflict with existing routes.
  When: When `/admin` is not desired. When NOT: Don’t set `path('')` if `/` is already routed in `routes/web.php`.
  Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path”
- Rule: Use render hooks to inject Blade content into Filament layouts without publishing internal views.
  When: When inserting banners/scripts/partials into specific layout locations. When NOT: Don’t publish Filament views for small layout tweaks.
  Source: https://filamentphp.com/docs/5.x/advanced/render-hooks — “Registering render hooks”

## Navigation — Groups, Ordering, Visibility
- Rule: Navigation is built from resources/pages/clusters and can be grouped, sorted, and conditionally shown/hidden.
  When: Always—use groups/sorting for predictable IA. When NOT: Don’t treat “hidden navigation” as authorization; still enforce policies/access checks.
  Source: https://filamentphp.com/docs/5.x/navigation/overview — “Introduction”
- Rule: Clusters group resources/pages under a single nav item and provide sub-navigation.
  When: When the sidebar becomes too large and needs hierarchy. When NOT: Don’t cluster if it reduces discoverability for your users.
  Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction”
- Rule: Cluster code structure (moving pages/resources into a cluster directory) is recommended, not required; behavior depends on `$cluster`.
  When: When you want consistent organization. When NOT: Don’t treat the directory layout as mandatory.
  Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters”
- Rule: The user menu is configured via `userMenuItems()` with Action objects and supports conditional visibility and sidebar placement.
  When: When adding account-related links/actions. When NOT: Don’t put destructive actions there without confirmation + authorization.
  Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction”

## Theming & Branding — CSS Hooks, Colors, Icons
- Rule: Filament exposes CSS hook classes (prefixed `fi-`) and recommends discovering them via browser DevTools.
  When: When styling core UI safely. When NOT: Don’t rely on brittle selectors; request/PR missing hooks instead of hacking around them.
  Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes”
- Rule: Apply styling by targeting hook classes (including Tailwind `@apply`) and use `!important` sparingly.
  When: When overriding default spacing/appearance in a maintainable way. When NOT: Don’t blanket `!important` your theme.
  Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Applying styles to hook classes”
- Rule: Customize the default semantic color palettes via `FilamentColor::register()` (e.g., primary, danger, etc.).
  When: When aligning Filament semantics to your brand palette. When NOT: Don’t hardcode per-component hex values when semantics suffice.
  Source: https://filamentphp.com/docs/5.x/styling/colors — “Customizing the default colors”
- Rule: Replace default UI icons globally via `FilamentIcon::register()` (icon aliases map to your chosen icons).
  When: When standardizing iconography or switching icon sets. When NOT: Don’t hardcode SVGs everywhere when aliases cover the UI.
  Source: https://filamentphp.com/docs/5.x/styling/icons — “Replacing the default icons”

## Asset System — Global + Lazy / On-Demand
- Rule: Register shared assets via `FilamentAsset::register()`; assets are published into `/public` when `php artisan filament:assets` runs.
  When: For app/plugin assets loaded by Filament. When NOT: Don’t assume assets exist in production without the publish step.
  Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade”
- Rule: Lazy-load CSS with `x-load-css` and prevent auto-loading via `loadedOnRequest()` for page-specific styles.
  When: For heavy CSS used only on certain pages/components. When NOT: Don’t lazy-load tiny styles used everywhere.
  Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS”
- Rule: Lazy-load JavaScript with `x-load-js` and prevent auto-loading via `loadedOnRequest()` for page-specific scripts.
  When: For heavy JS libraries used only on a subset of pages/widgets. When NOT: Don’t lazy-load scripts required for baseline panel behavior.
  Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading JavaScript”

## Plugin System — Mechanics + Panel Scoping
- Rule: Panel plugins integrate via a Plugin object; standalone plugins integrate via a service provider (no panel binding).
  When: When deciding whether a package needs panel-specific registration. When NOT: Don’t force a Plugin object for standalone-only components.
  Source: https://filamentphp.com/docs/5.x/plugins/getting-started — “The Plugin object”
- Rule: Plugin assets should be registered in the plugin’s service provider so Filament can manage publishing/loading.
  When: When shipping CSS/JS/Alpine components with a package. When NOT: Don’t register package assets ad-hoc only in app panel providers.
  Source: https://filamentphp.com/docs/5.x/plugins/getting-started — “Registering assets”
- Rule: Panel-scoped module/plugin registration can be centralized using `Panel::configureUsing()` for modular architectures.
  When: When modules should enable Filament artifacts only for specific panels. When NOT: Don’t register all modules globally if panels target different audiences.
  Source: https://filamentphp.com/docs/5.x/advanced/modular-architecture — “Registering plugins conditionally for specific panels”
- Rule: Panel plugins are configurable per panel; treat “enabled in panel A” and “enabled in panel B” as independent configuration contexts.
  When: When the same app has multiple panels with different modules enabled. When NOT: Don’t assume a plugin is active across all panels.
  Source: https://filamentphp.com/docs/5.x/plugins/panel-plugins — “Introduction”

## Actions — Modals, Confirmation, Execution
- Rule: Use `Action::make(...)->action(...)` to execute logic; use `requiresConfirmation()` for confirmation modals.
  When: For destructive or high-impact actions. When NOT: Don’t skip confirmation for destructive operations.
  Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals”
- Rule: Action modals can render a schema to collect input; submitted modal data is available to the action handler.
  When: When you need “form-in-action” workflows. When NOT: Don’t create bespoke modals when schema-in-modal is sufficient.
  Source: https://filamentphp.com/docs/5.x/actions/modals — “Rendering a form in a modal”

## Resources & Pages — Global Search, Queries
- Rule: Global search returns results for a resource only if it has an Edit or View page; otherwise the resource returns no results.
  When: When enabling global search for a resource. When NOT: Don’t expect global search on resources without Edit/View pages.
  Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles”
- Rule: If global search result details access relationships, override the global search query to eager-load them to avoid N+1.
  When: Any time you return relationship-backed details. When NOT: Don’t lazy-load relationships in global search rendering.
  Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results”
- Rule: You can disable search term splitting for performance on large datasets.
  When: When global search becomes expensive. When NOT: Don’t disable if multi-word relevance is important.
  Source: https://filamentphp.com/docs/5.x/resources/global-search — “Disabling search term splitting”

## Tables — Empty States
- Rule: Tables support empty-state content and can add empty-state actions to guide first-time users.
  When: Always—empty-state guidance improves “first run” UX. When NOT: Don’t leave empty lists without a clear next step when creation is expected.
  Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions”

## Testing
- Rule: Filament testing distinguishes Livewire components (pages/relation managers/widgets) from non-Livewire classes (resources/actions/schema objects).
  When: When choosing what to mount with `Livewire::test()`. When NOT: Don’t try to Livewire-test non-Livewire classes directly.
  Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?”
- Rule: Actions have dedicated testing guidance; follow it for asserting action execution and side effects.
  When: When actions drive critical business workflows. When NOT: Don’t leave actions untested if they mutate data or trigger external effects.
  Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions”

## OPINIONATED — best practices not explicitly mandated by docs
- Rule: Standardize destructive actions: danger styling + requiresConfirmation() + policy authorization + success/error notification.
  When: For delete/force-delete/restore/bulk destructive ops. When NOT: For trivial, reversible toggles.

## UNVERIFIED — not explicitly stated in the cited v5 pages above
- Rule: If you need confirmation or a modal, prefer `->action(...)` + `->requiresConfirmation()`; use `->url(...)` for navigation links.
  When: When deciding whether an action should execute vs navigate. When NOT: Don’t assume modal/confirmation behavior for URL-only actions without verifying in docs.
  Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals”