wezlo/filament-search-spotlight
A full-screen Spotlight command palette for Filament panels. Hit ⌘K to search records, resources, pages, and actions in one overlay, with recents and pins saved to localStorage. Composes Filament's GlobalSearchProvider, so globally searchable resources appear automatically. Configurable key binding,...
Build vs. buy for the "jump to anything" problem. A command palette is a deceptively expensive feature: overlay UX, fuzzy matching, keyboard handling, result ranking, empty states, i18n. This package collapses that to a composer require plus one plugin registration, and reuses Filament's GlobalSearchProvider instead of re-implementing search. If your roadmap item reads "make the admin faster to navigate," this is a two-day spike, not a two-sprint epic. The decision this informs is: do we spend engineering on search, or on the domain features only we can build?
Where your search backlog actually is. The Records category only shows resources that already implement getGloballySearchableAttributes(). Installing this is effectively a free audit: if the palette feels empty, you have a concrete, estimable backlog of "add global search attributes to resource X" tickets — cheap wins that also improve Filament's native topbar search. Use the install as a diagnostic before committing to a search initiative.
Whether to consolidate or supplement the search entry point. ->disableDefaultGlobalSearch() is a genuine product decision, not a config toggle. Two competing search affordances (topbar input + ⌘K overlay) dilute the mental model; one is cleaner but forces a habit change on users who live in the topbar. Decide deliberately, and pair it with the pilot below.
What deserves to be one keystroke away. The SpotlightAction registry is a product surface: it is a prioritized list of your product's "verbs." Curation here is roadmap work — "Create Invoice," "Impersonate user," "Open queue monitor," "Clear cache" says more about what your team does daily than any nav structure. The global registry (cross-cutting ops, every panel) vs. plugin-scoped registry (panel's own domain, overridable by name) split maps cleanly onto ownership boundaries, letting one panel retune a shared action without forking.
Extending search to domain objects without owning search infrastructure. The Category contract is a small interface — a search(query, limit) returning result objects. That means "index our settings pages / knowledge base / saved views" is an afternoon, not a Meilisearch or Algolia evaluation, an index pipeline, or a recurring vendor line item. It also frames the trade-off honestly: this is in-request, per-panel, provider-composed search. Good enough for internal tooling; not a substitute for a real search backend.
Scope decisions it removes from the table. Recent and pinned items live in browser localStorage under spotlight.recent / spotlight.pinned. No migrations, no schema, no data-retention review, no PII surface, nothing to clear on logout. For a PM in a regulated or privacy-sensitive org, that's a meaningfully shorter approval path — and the reason you can ship this in a week rather than a quarter.
What you are explicitly choosing not to have. No server-side history means no query analytics. You will not learn what people searched for, what returned zero results, or which actions nobody touches. If search quality is a strategic bet, budget instrumentation as a separate, self-built follow-up — or accept that your success signal is qualitative (pilot feedback, support-ticket volume) rather than a dashboard.
Adopt when most of the following hold:
getGloballySearchableAttributes() — or you can commit the small backlog to get them there. This single fact determines whether the demo lands as magic or as an empty box.@source step into your build pipeline: the package's views must be scanned or the overlay renders unstyled, and the fix has to survive deploys where vendor/ is reinstalled after assets are built. Treat this as part of install, not a follow-up ticket.Look elsewhere — or plan to build — when:
SpotlightActions and custom categories are plain labels and URLs; they do not get policy checks for free. A global "Impersonate user" or "Clear cache" entry needs its own gating (->visible(fn () => ...)-style checks and server-side authorization on the target route), plus audit logging if your threat model requires it. Do not let a convenience palette become a privilege-boundary hole.@source inclusion fragile. This is a real, predictable source of "it looks broken in prod" incidents.To executives (one paragraph): Our admin panel has grown to the point where finding things costs real time — users hunt through navigation for records they already know exist. This package gives us a full-screen ⌘K command palette in roughly a day of engineering: search across records, pages, and actions from one keyboard shortcut, with recent and pinned items remembered in the browser. There is no database work, no migration, no new infrastructure, and no new vendor contract — recent/pinned state never leaves the user's browser, so there's no data-retention or privacy review to run. It builds on Filament's existing search, so the resources we've already configured appear automatically. Total cost is one to two engineering days plus a small cleanup of searchable-attribute definitions across resources — cleanup that improves the existing search too. It is a one-line removal if we don't like it, and it is gated behind a small pilot, so the downside is bounded.
To engineering (the honest version): We're not asking you to build a palette. Register the plugin, add the @source line to the panel theme and rebuild, then audit getGloballySearchableAttributes() across resources — that audit is the actual work, and it's the thing that decides whether this feels good. Start narrow: ship the overlay with ->disableDefaultGlobalSearch() and three or four curated SpotlightActions that reflect daily rituals, rather than opening with custom categories. Split the action registry along ownership lines (global in AppServiceProvider for cross-cutting ops, plugin-scoped for panel domain). Two constraints to respect: custom actions and categories bypass resource policies, so every one you register needs its own authorization check and a guarded destination route; and this is a 1.0.x package with a single maintainer, so pin the version, keep a smoke test around the overlay opening and a result activating, and accept that an internal fork is the likely long-term home if we lean on it.
How we'll know it worked (propose these up front, since the package won't tell us): number of distinct weekly active admins who open the palette at least once; share of navigations that go through ⌘K versus the menu; time-to-create for the top three create flows; and — the cheapest and most convincing signal — a measurable drop in "where do I find X?" support pings from the pilot group. Run the pilot with five to eight heavy admin users for two weeks before deciding on panel-wide rollout and on retiring the topbar search.
How can I help you explore Laravel packages today?