kind-work/meili-search
A Laravel package that integrates Meilisearch for fast, typo-tolerant full-text search. Index Eloquent models, run instant search queries, and keep results in sync automatically. Simple configuration and an expressive API make it easy to add powerful search to any Laravel app.
composer require kind-work/meili-searchphp artisan vendor:publish --tag=meili-search-config.env: MEILISEARCH_HOST, MEILISEARCH_KEY (defaults to http://localhost:7700)config/meili-search.php or via a model trait; include the model’s searchable fieldsSearchable trait, implementing toSearchableArray(), then running php artisan meili-search:import'title' => '{{ title }} — {{ slug }}')Model indexing
Use model observers or the provided trait to keep Meilisearch in sync on create/update/delete. Queue indexing for large models to avoid blocking requests.
Antlers-powered fields (v1.1.0+)
In your index definition or toSearchableArray(), define fields as Antlers strings. The package parses them against the model/entry, so you can concatenate, format dates, strip HTML, or conditionally include values. Example: 'summary' => '{{ excerpt | strip_tags | truncate:160 }}'.
Multiple indexes per model
Define separate index configs with searchableAs() and custom field mappings. Use this for public vs. admin search, or for language-specific indexes.
Search queries
Query via the Meilisearch PHP client or the package’s facade: apply filters, facets, sorting, and pagination. Use filterableAttributes and sortableAttributes in index settings to enable advanced queries.
Bulk import and reindexing
Run php artisan meili-search:import with chunking; add --verbose to monitor. Schedule reindexing after large data migrations.
Statamic integration
If indexing Statamic entries, use Antlers transformations to enrich indexed data (e.g., {{ if featured }}featured{{ /if }}). Ensure the Antlers context matches the entry being indexed.
Conditional indexing
Implement shouldBeSearchable() to exclude drafts, private entries, or soft-deleted models from the index.
Antlers parsing overhead
Antlers transformations run per document during indexing. Cache expensive lookups (e.g., relationship counts) and avoid complex conditionals inside index definitions.
Field type consistency
Meilisearch infers types from the first document. Mixed types (null vs. string, int vs. float) across documents can cause indexing errors. Normalize values in your Antlers expressions or toSearchableArray().
Schema changes require reindex
Changing filterableAttributes, sortableAttributes, or field mappings requires flushing and reimporting: php artisan meili-search:flush && php artisan meili-search:import.
Config caching
php artisan config:cache can freeze index definitions and Antlers strings. Clear the cache after changing index configs.
Debugging failed documents
Meilisearch rejects invalid payloads. Enable MEILISEARCH_DEBUG=true to log requests, and check storage/logs/laravel.log for indexing exceptions. Use php artisan meili-search:status if provided.
Antlers escaping
Antlers may output HTML entities. Use | strip_tags or | raw deliberately; otherwise search results may contain unwanted markup.
Extension points
Override toSearchableArray() or bind a custom transformer to post-process Antlers output. Listen for package events (e.g., MeiliSearchIndexed) if you need to trigger downstream actions.
Queue workers
If indexing is queued, ensure workers are running and have the correct environment variables. Failed jobs will silently drop documents from the index.
How can I help you explore Laravel packages today?