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

Livewire Spotlight Search Laravel Package

tnt-freskim-veliu/livewire-spotlight-search

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies Ensure your project has:

    composer require livewire/livewire tnt-freskim-veliu/livewire-spotlight-search
    npm install alpinejs tailwindcss
    

    Verify Tailwind is configured in resources/css/app.css and Alpine is included in your layout.

  2. Publish Config Run:

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

    Update config/livewire-spotlight-search.php with your Searchable class (e.g., App\SpotlightSearch\UserSearch).

  3. Add Script Directive Include this in your Blade layout (e.g., resources/views/layouts/app.blade.php):

    @livewireSpotlightSearchScript
    
  4. Render the Component Place the component in your Blade view:

    <livewire:spotlight-search />
    
  5. Create a Searchable Class Implement the Searchable contract in a class (e.g., app/SpotlightSearch/UserSearch.php):

    use TNTFreskimVeliu\LivewireSpotlightSearch\Contracts\Searchable;
    
    class UserSearch implements Searchable {
        public function search(string $query): array { ... }
        public function group(): string { return "Users"; }
    }
    
  6. Test the Search Refresh the page and type in the spotlight input to see results.


Implementation Patterns

Core Workflow

  1. Define Searchable Models Create a Searchable class for each model/type you want to search (e.g., UserSearch, ProductSearch). Example:

    class ProductSearch implements Searchable {
        public function search(string $query): array {
            return Product::query()
                ->where('name', 'like', "%$query%")
                ->orWhere('sku', 'like', "%$query%")
                ->take(10)
                ->get()
                ->toArray();
        }
        public function group(): string { return "Products"; }
    }
    
  2. Configure Multiple Searchables Update the config to support multiple search types:

    return [
        'searchable' => [
            'users' => App\SpotlightSearch\UserSearch::class,
            'products' => App\SpotlightSearch\ProductSearch::class,
        ],
    ];
    
  3. Customize UI Override the default Tailwind styles by publishing views:

    php artisan vendor:publish --tag=livewire-spotlight-search-views
    

    Modify resources/views/vendor/livewire-spotlight-search/spotlight-search.blade.php.

  4. Dynamic Query Building Use Laravel Query Builder features for complex searches:

    public function search(string $query): array {
        return User::query()
            ->when($query, fn($q) => $q->where(function($query) use ($query) {
                $query->where('name', 'like', "%$query%")
                      ->orWhere('email', 'like', "%$query%");
            }))
            ->take(20)
            ->get()
            ->toArray();
    }
    
  5. Integration with Livewire Properties Extend the component by creating a custom Livewire class:

    class CustomSpotlightSearch extends \TNTFreskimVeliu\LivewireSpotlightSearch\SpotlightSearch {
        public function mount() {
            $this->searchable = new App\SpotlightSearch\UserSearch();
        }
    }
    

    Use it in Blade:

    <livewire:custom-spotlight-search />
    
  6. Alpine.js Extensions Enhance reactivity with Alpine.js (e.g., auto-focus, debounce):

    <input
        x-data="{ debounce: null }"
        x-on:input.debounce="debounce = setTimeout(() => $wire.search($event.target.value), 300)"
        x-on:blur="clearTimeout(debounce)"
        wire:model="query"
    >
    

Gotchas and Tips

Pitfalls

  1. Missing Dependencies

    • Issue: Forgetting to include Alpine.js or TailwindCSS.
    • Fix: Ensure @alpinejs and Tailwind are loaded in your layout. Add to resources/js/app.js:
      import Alpine from 'alpinejs';
      window.Alpine = Alpine;
      Alpine.start();
      
  2. Searchable Contract Not Implemented

    • Issue: Classes not implementing Searchable or missing required methods (search, group).
    • Fix: Verify the class implements TNTFreskimVeliu\LivewireSpotlightSearch\Contracts\Searchable and includes both methods.
  3. Case Sensitivity in LIKE Queries

    • Issue: LIKE queries may be case-sensitive depending on the database collation.
    • Fix: Use LOWER() or ILIKE (PostgreSQL) for case-insensitive searches:
      ->where('name', 'LIKE', "%{$query}%")
      
      or
      ->whereRaw('LOWER(name) LIKE LOWER(?)', ["%{$query}%"])
      
  4. Performance with Large Datasets

    • Issue: Slow searches on tables with millions of records.
    • Fix:
      • Add database indexes to searched columns.
      • Limit results with take() (default is 25).
      • Use database-specific full-text search (e.g., PostgreSQL tsvector, MySQL MATCH AGAINST).
  5. Caching Search Results

    • Issue: Repeated searches for the same query hit the database unnecessarily.
    • Fix: Cache results in the search method:
      public function search(string $query): array {
          return Cache::remember("spotlight_{$query}", now()->addMinutes(5), function() use ($query) {
              return User::query()->where('name', 'like', "%$query%")->take(25)->get()->toArray();
          });
      }
      
  6. Tailwind CSS Conflicts

    • Issue: Styling clashes with existing Tailwind classes.
    • Fix: Override styles in your custom component or use utility classes like !important sparingly:
      <div class="spotlight-result !bg-blue-100">...</div>
      
  7. Alpine.js XSRF Protection

    • Issue: Livewire + Alpine interactions may trigger CSRF errors.
    • Fix: Ensure @csrf is in your layout and use wire:key for dynamic components:
      <div wire:key="search-{{ $query }}">...</div>
      

Debugging Tips

  1. Log Search Queries Add logging to the search method to debug queries:

    public function search(string $query): array {
        \Log::debug("Search query: {$query}");
        return User::query()->where('name', 'like', "%$query%")->get()->toArray();
    }
    
  2. Check Livewire Wire:ignore If the component isn’t updating, ensure dynamic elements aren’t wrapped in wire:ignore:

    <!-- Bad: Blocks reactivity -->
    <div wire:ignore>
        <input x-model="query">
    </div>
    
    <!-- Good: Allows Alpine + Livewire -->
    <div>
        <input x-model="query" wire:model="query">
    </div>
    
  3. Verify Published Config After publishing, check config/livewire-spotlight-search.php for typos or incorrect class names.

  4. Clear Blade Cache If changes aren’t reflecting, clear the cache:

    php artisan view:clear
    php artisan cache:clear
    

Extension Points

  1. Custom Result Rendering Override the result template in resources/views/vendor/livewire-spotlight-search/spotlight-search.blade.php:

    @foreach($results as $result)
        <div class="p-2 border-b">
            <h3 class="font-bold">{{ $result['name'] }}</h3>
            <p class="text-sm text-gray-500">{{ $result['email'] }}</p>
        </div>
    @endforeach
    
  2. Add Search Filters Extend the component to support filters (e.g., search by role):

    public function search(string $query, ?string $role = null): array {
        $query = User::query()->where('name', 'like', "%$query%");
        if ($role) $query->where('role', $role);
        return $query->take(25)->get()->toArray();
    }
    

    Pass filters via Livewire properties or URL parameters.

  3. Integration with Laravel Scout For advanced search, replace the search method with Scout:

    public function search(string $query): array {
        return User::
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle