Search Spotlight plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Search Spotlight

A full-screen Spotlight / command-palette search overlay for Filament panels. Opens on ⌘K (configurable), aggregates results from multiple categories (records, resources, pages, actions, plus recent/pinned from localStorage), and composes Filament's built-in `GlobalSearchProvider` — every resource that already implements `getGloballySearchableAttributes()` shows up automatically.

Tags: Panels
Supported versions:
5.x 4.x
Mustafa Khaled avatar Author: Mustafa Khaled

Documentation

A full-screen Spotlight / command-palette search overlay for Filament panels. Opens on ⌘K (configurable), aggregates results from multiple categories (records, resources, pages, actions, plus recent/pinned from localStorage), and composes Filament's built-in GlobalSearchProvider — every resource that already implements getGloballySearchableAttributes() shows up automatically.

#Features

  • ⌘K / Ctrl+K overlay, single-column centered layout
  • Categories out of the box:
    • Records — delegates to the panel's GlobalSearchProvider, attaches the resource's navigation icon to each result
    • Resources — jump to any resource's index page by its plural label
    • Pages — fuzzy-matches standalone panel pages by navigation label
    • Actions — fluent SpotlightAction registry + auto-generated "Create {Resource}" entries for resources with a create page
  • Recent & pinned items persisted in browser localStorage (no DB, no migrations)
  • Keyboard navigation: arrow keys wrap, enter activates, escape closes
  • Single-click (or enter) to activate; hover syncs the highlighted row
  • Fully configurable per panel and globally via config file

#Installation

composer require wezlo/filament-search-spotlight

Register the plugin on your panel:

use Wezlo\FilamentSearchSpotlight\FilamentSearchSpotlightPlugin;

->plugins([
    FilamentSearchSpotlightPlugin::make(),
])

That's it — press ⌘K inside any panel page.

If your panel uses a compiled Tailwind theme (e.g. resources/css/filament/admin/theme.css), make sure it scans the package's views so utility classes are generated:

@source '../../../../vendor/wezlo/filament-search-spotlight/resources/views/**/*';

Then rebuild with npm run build / npm run dev.

#Configuration

Publish the config file (optional):

php artisan vendor:publish --tag=filament-search-spotlight-config

Every option is settable fluently on the plugin or in config/filament-search-spotlight.php. Fluent calls win over config values.

#Fluent API

FilamentSearchSpotlightPlugin::make()
    // Keyboard binding (Mousetrap syntax). Accepts a string or an array.
    ->keyBinding('mod+k')

    // Placeholder text for the search input.
    ->placeholder('Jump to…')

    // Any valid CSS width (rem, px, vw, %, …). Applied as an inline style so
    // it is not subject to Tailwind purging.
    ->maxWidth('36rem')

    // Max results per category.
    ->resultLimitPerCategory(8)

    // Toggle built-in categories (all default on).
    ->records()           // records(false) to hide
    ->resources()
    ->pages()
    ->actionsEnabled()

    // Or completely override the category list with your own.
    ->categories([MyCustomCategory::class])

    // Exclude resources from both the Records and Resources categories
    // (also prevents their auto-generated Create action).
    ->excludeResources([AuditLogResource::class])

    // Register actions scoped to this panel (on top of the global registry).
    ->action(
        SpotlightAction::make('log-out')
            ->label('Log out')
            ->icon('heroicon-o-arrow-right-on-rectangle')
            ->keywords(['signout', 'quit'])
            ->group('Account')
            ->url(fn () => filament()->getLogoutUrl()),
    )
    ->actions([
        SpotlightAction::make('impersonate')->label('Impersonate user')->url('/impersonate'),
    ])

    // Hide actions registered in the global registry by name. Plugin-scoped
    // actions with the same name automatically override their global twin,
    // so overrideActions() is only needed when you want to hide without
    // replacing.
    ->overrideActions(['legacy-action'])

    // Skip the auto-generated "Create {Resource}" entries entirely.
    ->disableCreateActions()

    // Remove Filament's in-topbar global search input in favor of the overlay.
    ->disableDefaultGlobalSearch();

#Config file

return [
    'key_binding' => 'mod+k',

    'result_limit_per_category' => 8,

    'excluded_resources' => [],

    'disable_default_global_search' => false,

    'categories' => [
        'records' => true,
        'resources' => true,
        'pages' => true,
        'actions' => true,
    ],

    'disable_create_actions' => false,

    'placeholder' => 'Search…',

    'max_width' => '42rem',

    'override_actions' => [],
];

#Actions

#Fluent SpotlightAction

use Wezlo\FilamentSearchSpotlight\Actions\SpotlightAction;

SpotlightAction::make('log-out')
    ->label('Log out')
    ->icon('heroicon-o-arrow-right-on-rectangle')
    ->keywords(['signout', 'quit'])
    ->group('Account')
    ->url(fn () => filament()->getLogoutUrl());

#Global registry

Call ->register() to add an action to the app-wide registry (available to every panel using the plugin). Typically done in AppServiceProvider::boot():

public function boot(): void
{
    SpotlightAction::make('clear-cache')
        ->label('Clear application cache')
        ->keywords(['flush', 'cache'])
        ->url(fn () => route('admin.cache.clear'))
        ->register();
}

#Plugin-scoped actions

Pass actions directly to the plugin when you only want them on a specific panel, or when you want to override a registry action with the same name:

FilamentSearchSpotlightPlugin::make()
    ->action(SpotlightAction::make('log-out')->label('Custom Log out')->url('/custom-logout'));

A plugin-scoped action with the same name as a registry action automatically replaces the registry one in the overlay.

#Auto-discovered "Create X" actions

Any resource exposing a create page is automatically surfaced as a Create {Label} action. Disable with ->disableCreateActions() or the disable_create_actions config value.

#Adding a custom category

Categories are tiny — implement the Category contract:

use Wezlo\FilamentSearchSpotlight\Categories\Category;
use Wezlo\FilamentSearchSpotlight\Data\SpotlightResult;

class SettingsCategory implements Category
{
    public function key(): string { return 'settings'; }

    public function label(): string { return 'Settings'; }

    public function search(string $query, int $limit): array
    {
        return collect($this->all())
            ->filter(fn ($item) => str_contains(strtolower($item['label']), strtolower($query)))
            ->take($limit)
            ->map(fn ($item) => new SpotlightResult(
                id: 'settings:'.$item['key'],
                category: 'settings',
                title: $item['label'],
                subtitle: null,
                icon: 'heroicon-o-cog-6-tooth',
                url: $item['url'],
            ))
            ->values()
            ->all();
    }

    protected function all(): array { /**/ }
}

Register it by overriding the default category list:

FilamentSearchSpotlightPlugin::make()
    ->categories([
        \Wezlo\FilamentSearchSpotlight\Categories\RecordsCategory::class,
        \Wezlo\FilamentSearchSpotlight\Categories\ResourcesCategory::class,
        SettingsCategory::class,
    ]);

#Recent & pinned

Both lists are owned client-side in localStorage under spotlight.recent and spotlight.pinned. Activating a result appends it to recent (deduped, max 10). Nothing is persisted server-side, so there is no database migration to run and no state to clear on logout.

#Tests

Feature tests live alongside the consumer app under tests/Feature/FilamentSearchSpotlight/:

php artisan test --compact tests/Feature/FilamentSearchSpotlight

The author

Mustafa Khaled avatar Author: Mustafa Khaled

15 Year Laravel Developer

Plugins
10
Stars
1

From the same author

Workspace Tabs plugin thumbnail

Workspace Tabs

Browser-like tabs for Filament panels. Open multiple pages in tabs without losing context, drag to reorder, pin frequently accessed pages, and right-click for quick actions.

Mustafa Khaled avatar Author: Mustafa Khaled
5 stars
Tag: Panels Tag: Kit More tags: +1
Dark mode ready Multilingual support
Free
Get it now
Export Pro plugin thumbnail

Export Pro

A comprehensive, model-agnostic export engine for Filament. Handles large datasets with background processing and real-time progress tracking, maintains full export history with audit trails, supports scheduled/recurring exports with delivery, and gives admins visibility into who exported what and when.

Mustafa Khaled avatar Author: Mustafa Khaled
0 stars
Tag: Action Tag: Developer Tool More tags: +3
Dark mode ready Multilingual support
$99.00
Buy now
Record Freezer plugin thumbnail

Record Freezer

Freeze individual Eloquent records against modification — finalised contracts, audited financial periods, legal holds

Mustafa Khaled avatar Author: Mustafa Khaled
2 stars
Tag: Panels Tag: Developer Tool More tags: +1
No dark mode support No multilingual support
Free
Get it now
Record Watcher plugin thumbnail

Record Watcher

Subscribe to individual Eloquent records and receive in-panel Filament notifications whenever they change — with the actor (who) and a field-level diff (what). Watches can carry conditions ("only if status changes", "only if amount > 10K"), can be paused, and live on a personal **My Watches** page scoped to the authenticated user. Every fan-out is also persisted to a permanent event log, so users can review the full change history even after dismissing notifications.

Mustafa Khaled avatar Author: Mustafa Khaled
1 star
Tag: Action Tag: Developer Tool More tags: +2
Dark mode ready Multilingual support
Free
Get it now