Weave Code
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

Meilisearch Php Laravel Package

meilisearch/meilisearch-php

Official PHP client for Meilisearch, the open‑source search engine. Connect to Meilisearch or Meilisearch Cloud to index documents, configure indexes, and run fast, typo‑tolerant searches. Supports customizable HTTP clients and common PHP tooling.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup in Laravel
1. **Install the package** with Guzzle (recommended):
   ```bash
   composer require meilisearch/meilisearch-php guzzlehttp/guzzle http-interop/http-factory-guzzle:^1.0
  1. Configure the client in a service provider (e.g., AppServiceProvider):
    public function register()
    {
        $this->app->singleton(Meilisearch\Client::class, function ($app) {
            return new Meilisearch\Client(
                env('MEILISEARCH_HOST', 'http://127.0.0.1:7700'),
                env('MEILISEARCH_MASTER_KEY', 'masterKey')
            );
        });
    }
    
  2. First use case: Index documents in a Laravel model observer or controller:
    $client = app(Meilisearch\Client::class);
    $index = $client->index('products');
    $index->addDocuments([['id' => 1, 'name' => 'Laptop', 'price' => 999]]);
    

Key Resources


Implementation Patterns

Common Workflows

1. Search Integration

Pattern: Use in Laravel controllers for search-as-you-type:

public function search(Request $request)
{
    $query = $request->input('q');
    $index = app(Meilisearch\Client::class)->index('products');

    $results = $index->search($query, [
        'limit' => 10,
        'attributesToRetrieve' => ['id', 'name', 'price'],
        'attributesToHighlight' => ['name']
    ]);

    return response()->json($results->getHits());
}

2. Real-Time Updates

Pattern: Sync database changes to Meilisearch via model observers:

// app/Observers/ProductObserver.php
public function saved(Product $product)
{
    $index = app(Meilisearch\Client::class)->index('products');
    $index->updateDocument($product->id, $product->toArray());
}

3. Search Facets

Pattern: Enable faceted navigation in Laravel views:

$index = app(Meilisearch\Client::class)->index('products');
$results = $index->search($query, [
    'facets' => ['categories', 'price_range']
]);

// Pass $results->getFacets() to Blade

4. Async Operations

Pattern: Handle long-running tasks with Laravel queues:

// Dispatch a job for bulk indexing
IndexProductsJob::dispatch($products);

// In the job
public function handle()
{
    $index = app(Meilisearch\Client::class)->index('products');
    $index->addDocuments($this->products);
}

Integration Tips

  1. Laravel Service Container: Bind the client to the container with custom configurations:

    $this->app->bind(Meilisearch\Client::class, function ($app) {
        $client = new Meilisearch\Client(
            env('MEILISEARCH_HOST'),
            env('MEILISEARCH_MASTER_KEY'),
            new GuzzleHttp\Client(['timeout' => 5])
        );
        return $client;
    });
    
  2. API Key Management: Use the typed query objects (v2+) for security:

    $key = $client->createKey(new CreateKeyQuery(
        actions: [KeyAction::Search],
        indexes: ['products'],
        description: 'Public search key'
    ));
    
  3. Search Middleware: Create middleware to inject search results:

    public function handle($request, Closure $next)
    {
        $request->merge([
            'search_results' => $this->search($request->query('q'))
        ]);
        return $next($request);
    }
    
  4. Testing: Use Laravel's Meilisearch facade in tests:

    public function testSearch()
    {
        $client = $this->app->make(Meilisearch\Client::class);
        $index = $client->index('test_products');
        $index->addDocuments([['id' => 1, 'name' => 'Test Product']]);
    
        $results = $index->search('test');
        $this->assertCount(1, $results->getHits());
    }
    

Gotchas and Tips

Pitfalls

  1. Async Operations:

    • Gotcha: addDocuments() returns immediately but may take time to process.
    • Fix: Use the task UID to track status:
      $taskUid = $index->addDocuments($docs)->getTaskUid();
      $task = $client->waitForTask($taskUid);
      
  2. Index Settings:

    • Gotcha: Changing filterableAttributes or searchableAttributes triggers a full index rebuild.
    • Fix: Monitor task progress with $client->getTask($taskUid).
  3. Highlighting:

    • Gotcha: attributesToHighlight must be defined in searchableAttributes.
    • Fix: Update index settings first:
      $index->updateSearchableAttributes(['name', 'description']);
      
  4. Pagination:

    • Gotcha: offset/limit can be slow for large datasets.
    • Fix: Use cursor-based pagination with after parameter (Meilisearch v1.30+).
  5. Typo Tolerance:

    • Gotcha: Typos are enabled by default but may impact performance.
    • Fix: Adjust typoTolerance setting:
      $index->updateTypoTolerance('lenient');
      

Debugging Tips

  1. Enable Debug Mode:

    $client = new Meilisearch\Client(
        'http://localhost:7700',
        'masterKey',
        new GuzzleHttp\Client(['debug' => true])
    );
    
  2. Check Tasks: List pending tasks to debug slow operations:

    $tasks = $client->getAllTasks();
    foreach ($tasks as $task) {
        if ($task->status === 'processing') {
            // Handle stuck tasks
        }
    }
    
  3. Validate Documents: Ensure documents have unique id fields to avoid duplicates:

    $documents = collect($products)->map(function ($product) {
        return ['id' => $product->id, 'name' => $product->name];
    })->toArray();
    

Extension Points

  1. Custom HTTP Client: Extend the client for retry logic or logging:

    $httpClient = new GuzzleHttp\Client([
        'timeout' => 10,
        'on_stats' => function (TransferStats $stats) {
            Log::debug('Meilisearch request', [
                'duration' => $stats->getHandlerStats()->getDuration(),
                'size' => $stats->getHandlerStats()->getTransferStats()->getSize()
            ]);
        }
    ]);
    
    $client = new Meilisearch\Client('http://localhost:7700', 'masterKey', $httpClient);
    
  2. Search Result Transformers: Create a transformer for consistent API responses:

    $results = $index->search($query)->getHits();
    $transformed = collect($results)->map(function ($hit) {
        return [
            'id' => $hit['id'],
            'title' => $hit['title'],
            'url' => route('products.show', $hit['id']),
            'highlighted_title' => $hit['_formatted']['title'] ?? null
        ];
    });
    
  3. Event Listeners: Listen for Meilisearch task completion:

    $client->onTaskCompleted(function ($task) {
        Log::info("Task {$task->uid} completed with status: {$task->status}");
    });
    
  4. Laravel Scout Alternative: Use the package as a drop-in replacement for Scout:

    // config/scout.php
    'driver' => 'meilisearch',
    
    // app/Providers/ScoutServiceProvider.php
    public function boot()
    {
        Scout::extend('meilisearch', function ($app) {
            return new MeilisearchEngine(
                $app->make(Meilisearch\Client::class)
            );
        });
    }
    

Configuration Quirks

  1. Environment Variables: Use Laravel's .env for sensitive data:

    MEILISEARCH_HOST=http://localhost:7700
    MEILISEARCH_MASTER_KEY=your_master_key
    MEILISEARCH_INDEX=products
    
  2. Index Creation:

    • Gotcha: Indexes are created automatically on first addDocuments().
    • Tip: Pre-create indexes with settings:
      $index = $client->index('products');
      $index->updateSettings([
      
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle