Simple search integration.
A demo of searching with Scout and Meilisearch.
This demo will use Scout and Meiliseach to demonstrate how simple it is to implement searching into your Laravel application.
Search for an Ubuntu release!
Showing 8 of 42 results.
Ubuntu 25.04
Plucky Puffin
Released: 17th April 2025
EOL: 31st January 2026
Ubuntu 24.10
Oracular Oriole
Released: 10th October 2024
EOL: 10th July 2025
Ubuntu 24.04 LTS
Noble Numbat
Released: 25th April 2024
EOL: 30th April 2029
Ubuntu 23.10
Mantic Minotaur
Released: 12th October 2023
EOL: 11th July 2024
Ubuntu 23.04
Lunar Lobster
Released: 20th April 2023
EOL: 25th January 2024
Ubuntu 22.10
Kinetic Kudu
Released: 20th October 2022
EOL: 20th July 2023
Ubuntu 22.04 LTS
Jammy Jellyfish
Released: 21st April 2022
EOL: 30th April 2022
Ubuntu 21.10
Impish Indri
Released: 14th October 2021
EOL: 14th July 2022
A quick walkthrough of how this works.
This walkthrough won't cover all aspects, but it should give you a good idea of how it all works.
My assumptions, are at the very least, are that you have Laravel setup with Livewire installed and configured and have an Meilisearch server running.
To use Scout and Meilisearch with Laravel, you first need to install some packages via composer can configure them.
For Meilisearch, run the following to install the packages.
composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
Then add the following environment variables to your .env
file, you should
update these to match your setup.
SCOUT_DRIVER=meilisearchMEILISEARCH_HOST=http://127.0.0.1:7700MEILISEARCH_KEY=masterKey
For Scout, run the following to install the packages.
composer require laravel/scoutphp artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
These commands will also generate a scout.php
config file, we will need to
touch this later on.
This demo needs some data for us to search through, for this we will create a model and a database migration so that we can store the data.
To create the model, we can run the following Artisan command, this will create a file
/app/Models/LinuxDistro.php
.
php artisan make:model LinuxDistro
Update the generated file to look like this.
1<?php 2 3namespace App\Models; 4 5use Carbon\Carbon; 6use Illuminate\Database\Eloquent\Model; 7use Laravel\Scout\Searchable; 8 9/**10 * @property int $id11 * @property string $name12 * @property string $codename13 * @property Carbon $release_date14 * @property Carbon $eol_date15 */16class LinuxDistro extends Model17{18 use Searchable;19 20 protected $fillable = [21 'name',22 'codename',23 'release_date',24 'eol_date'25 ];26 27 protected $casts = [28 'release_date' => 'date',29 'eol_date' => 'date',30 ];31 32 33 public $timestamps = false;34}
To allow us to store the data in the database, we need to create a migration to define our table, the
following command will create the migration file /database/migrations/2025_05_13_094648_create_linux_distros_table.php
,
your timestamp will obviously be different though.
php artisan make:migration create_linux_distros_table
Update the generated file to match the following.
1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7return new class extends Migration 8{ 9 /**10 * Run the migrations.11 */12 public function up(): void13 {14 Schema::create('linux_distros', function (Blueprint $table) {15 $table->id();16 $table->string('name');17 $table->string('codename');18 $table->date('release_date');19 $table->date('eol_date');20 });21 }22 23 /**24 * Reverse the migrations.25 */26 public function down(): void27 {28 Schema::dropIfExists('linux_distros');29 }30};
Finally, to apply this migration, we need to run one more Artisan command.
php artisan migrate
Now we have the model and database all setup, we can configure Scout and Meilisearch, we need to tell
Meiliseach what data is filterable and sortable, so inside the /config/scout.php
file, find the "Meilisearch Configuration" section and update it to this.
'meilisearch' => [ 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'), 'key' => env('MEILISEARCH_KEY'), 'index-settings' => [ LinuxDistro::class => [ 'filterableAttributes'=> ['name', 'codename'], 'sortableAttributes' => ['release_date', 'eol_date'], ], ],],
This needs to be synced with the Meilisearch server with the help of another Artisan command.
php artisan scout:sync-index-settings
Because we need some data to search, I will be seeding the database with a predefined set of data and Laravel makes this very easy, with seeder files.
php artisan make:seeder LinuxDistroSeeder
This will create the file /database/seeders/LinuxDistroSeeder.php
, below is
a cutdown version of what I have.
1<?php 2 3namespace Database\Seeders; 4 5use App\Models\LinuxDistro; 6use Carbon\Carbon; 7use Illuminate\Database\Seeder; 8 9class LinuxDistroSeeder extends Seeder10{11 /**12 * Run the database seeds.13 */14 public function run(): void15 {16 $distros = [17 [18 'name' => 'Ubuntu 24.04 LTS',19 'codename' => 'Noble Numbat',20 'release_date' => Carbon::createFromDate(2024, 4, 25),21 'eol_date' => Carbon::createFromDate(2029, 4, 30),22 ],23 [24 'name' => 'Ubuntu 24.10',25 'codename' => 'Oracular Oriole',26 'release_date' => Carbon::createFromDate(2024, 10, 10),27 'eol_date' => Carbon::createFromDate(2025, 7, 10),28 ],29 [30 'name' => 'Ubuntu 25.04',31 'codename' => 'Plucky Puffin',32 'release_date' => Carbon::createFromDate(2025, 4, 17),33 'eol_date' => Carbon::createFromDate(2026, 1, 31),34 ]35 ];36 37 foreach ($distros as $distro) {38 if (! LinuxDistro::where('name', $distro['name'])->first()) {39 $model = new LinuxDistro();40 $model->name = $distro['name'];41 $model->codename = $distro['codename'];42 $model->release_date = $distro['release_date'];43 $model->eol_date = $distro['eol_date'];44 $model->save();45 }46 }47 }48}
You can run the seeder with another Artisan command, this should then populate the database.
php artisan db:seed --class LinuxDistroSeeder
For Livewire components, you need a controller and a view, to generate these two files run the following Artisan command.
php artisan make:livewire Demos/Scout
This will create the files /app/Livewire/Demos/Scout.php
and
/resources/views/livewire/demos/scout.blade.php
, these files are
very simple, the first handles the server code or logic and the other is the view displayed to the user.
1<?php 2 3namespace App\Livewire\Demos; 4 5use App\Models\LinuxDistro; 6use Livewire\Component; 7 8class Scout extends Component 9{10 public $search = '';11 12 public function render()13 {14 $distros = LinuxDistro::search($this->search)15 ->orderByDesc('release_date')16 ->paginate(8);17 18 return view('livewire.demos.scout', [19 'distros' => $distros20 ]);21 }22}
1<div> 2 <div class="mb-4"> 3 <input type="text" 4 wire:model.live="search" 5 placeholder="Search for a release, i.e. Trusty" 6 class="w-full outline-none border-2 border-slate-300 focus:border-slate-400 rounded-lg pl-2 pr-8 py-2 transition"> 7 </div> 8 9 <div>10 @if ($distros->isEmpty())11 <p>No releases found.</p>12 @else13 @if ($distros->hasMorePages())14 <p>Showing {{ $distros->count() }} of {{ $distros->total() }} results.</p>15 @endif16 17 @foreach ($distros as $key => $distro)18 <div class="py-4 {{ $key > 0 ? 'border-t border-black' : '' }} lg:flex">19 <p class="text-xl lg:w-1/4">{{ $distro->name }}</p>20 <p class="text-lg lg:text-xl lg:w-1/4 text-slate-500 mb-2 lg:mb-0">{{ $distro->codename }}</p>21 <p class="lg:w-1/4">Released: {{ $distro->release_date->format('jS F Y') }}</p>22 <p class="lg:w-1/4">EOL: {{ $distro->eol_date->format('jS F Y') }}</p>23 </div>24 @endforeach25 @endif26 </div>27</div>
We now need to start creating our main frontend for the user to interact with, this will define the general layout and also include the Livewire component.
You can create a view with the following artisan command.
php artisan make:view demos/scout
This will create the file /resources/views/demos/scout.blade.php
, you can now
build this up to fit your design, below is a condensed version of my file, notice the Livewire element defined.
1<x-layouts.html 2 title="Laravel Scout - Demos" 3 pageTitle="Laravel Scout" 4 pageTagLine="Simple search integration." 5> 6 <x-content-container class="w-full mb-8"> 7 <div class="mb-8 text-left"> 8 <h2 class="text-2xl mb-2">Demo</h2> 9 <p class="mb-2 text-slate-500">A demo of searching with Scout and Meilisearch.</p>10 <x-gradent-under-line />11 </div>12 13 <div class="text-left"> 14 <x-content-text class="mb-8 text-2xl text-center">15 Search for an Ubuntu release!16 </x-content-text>17 18 <!-- Include the Livewire component -->19 <livewire:demos.scout />20 </div> 21 </x-content-container>22</x-layouts.html>
Finally, to enable people to access this page, we need to define a route in the
/routes/web.php
file.
Route::get('/demos/scout', function () { return view('demos/scout');})->name('demos.scout');