Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Meilisearch Laravel Package

lancodev/filament-meilisearch

Filament plugin that connects your admin panels to Meilisearch, adding fast, typo-tolerant full-text search to resources and tables with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

lancodev/filament-meilisearch wires Laravel Scout's Meilisearch engine into Filament's global search, so the top-bar search (and any plugin-provided search UI) queries Meilisearch instead of walking your Eloquent resources.

Requirements (as of v2.0.1):

  • PHP 8.2+, Laravel 11/12
  • Filament v4 or v5 only — v2.0.0 dropped Filament v3 support
  • laravel/scout installed and configured
  • A reachable Meilisearch instance (local binary, Docker, or Meilisearch Cloud)

Minimal setup:

  1. composer require lancodev/filament-meilisearch
  2. Publish the config: php artisan vendor:publish --tag="filament-meilisearch-config"
  3. In .env, point Scout at Meilisearch:
    SCOUT_DRIVER=meilisearch
    MEILISEARCH_HOST=http://127.0.0.1:7700
    MEILISEARCH_KEY=<master-or-admin-key>
    
  4. Register the plugin in your PanelProvider:
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugin(FilamentMeilisearchPlugin::make());
    }
    
  5. Add Laravel\Scout\Searchable to the models backing your resources and run php artisan scout:import "App\Models\Post".

Where to look first: the published config/filament-meilisearch.php (host/key/index naming and the search toggle) and the plugin's make() method in your panel provider — that is where per-panel behaviour is decided. Then check the package README's resource examples to confirm how a Filament resource opts into the external index.

First use case: replace Filament's default getGlobalSearchResults() DB LIKE queries on a large Post/Order table with Meilisearch-backed results — you get typo tolerance and relevance ranking for free, usually with no changes to your resource table columns.

Implementation Patterns

Per-resource opt-in. Typically a resource declares the searchable model and the columns/labels shown in results; keep that mapping in the resource rather than in the plugin so each panel can differ. Return lightweight result DTOs from the resource's global-search method and let the plugin handle the query.

Index shape first, UI second. Define toSearchableArray() deliberately — it is your search document, not your model. Flatten relations, strip large HTML blobs, and expose only fields you actually display or filter on.

Filterable attributes are a contract. Any where()/facet you apply at query time must exist in Meilisearch's filterableAttributes. Drive this from scout:sync-index-settings (Scout's searchableAs() plus the engine's index-settings config) so a fresh environment reproduces the same index as production.

Panels and tenancy. For multi-tenant apps, apply a tenant filter at query time (e.g. a where('tenant_id', ...) on the search) and add tenant_id to filterable attributes. Do not rely on separate indexes per tenant unless you have a strong isolation requirement — it multiplies index-management work.

Indexing pipeline. Keep SCOUT_QUEUE=true in production and index through Horizon/your queue worker; run scout:import on deploy for new models and after any toSearchableArray() change. For very large tables use makeAllSearchableUsing() with eager loads to avoid N+1 during import.

Local development. Run Meilisearch via Sail/Compose, and make seeding part of your setup script (scout:import after migrate:fresh --seed). Keep a .env.testing pointing at a disposable instance so feature tests exercise real ranking behaviour rather than a mocked engine.

Progressive rollout. Leave Filament's built-in global search enabled for small resources and route only the heavy ones through Meilisearch — the plugin and the default search coexist fine per resource.

Gotchas and Tips

  • Filament v3 is gone. v2.x targets Filament v4/v5 only. If you are mid-upgrade, pin ^1.0 for v3 panels and upgrade deliberately — the plugin registration API differs between major versions.
  • Document IDs must be Meilisearch-safe. Meilisearch document ids accept only alphanumerics, - and _. UUIDs and integer keys are fine, but prefixed/composite keys (post:1) will be rejected — override getScoutKey() if your model uses one.
  • Filtering "does nothing" is usually a settings problem. filterableAttributes and searchableAttributes live in the index, not in code. Re-run the settings sync and re-import; restart the Meilisearch container only if settings updates fail.
  • Ranking surprises. Default ranking rules prioritise words/typo/proximity over attribute position. If exact matches should win, set searchableAttributes in priority order and consider attributesToSearchOn per query.
  • Stale results after deletes. Soft-deleted models stay searchable unless Searchable is configured to remove them — verify your delete()/restore() observers and that queue workers are running. php artisan scout:status and scout:flush are your debugging levers.
  • Key confusion. The admin/master key is for indexing; the search-only key is for the browser. The panel queries server-side, so the admin key works — but never ship it to a Livewire-rendered client payload.
  • Typo tolerance on short tokens. minWordSizeForTypos defaults mean 3–4 character queries get no tolerance; tune it if users search SKUs or codes.
  • Debugging order: curl the index directly (GET /indexes/<index>/search?q=...) → confirm the document shape → confirm the plugin's query → check Filament resource visibility/authorisation (canViewAny, canGloballySearch) before assuming a search bug.
  • v2.0.1 is documentation-only. The only code-adjacent change is the filament-hidden class on the banner image; there is no migration work from v2.0.0. Treat this as a safe patch bump.
  • Extension point: the published config is the intended override surface for host/key/index prefix; prefer it over forking the plugin, since the plugin surface is small enough that config-level customisation rarely blocks you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo