Laravel Scout

Simple search integration.

Demo

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

Show Your Working

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.

Composer and Env Requirements

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=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

For Scout, run the following to install the packages.

composer require laravel/scout
php 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.

Model and Migration

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.

The Model

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 $id
11 * @property string $name
12 * @property string $codename
13 * @property Carbon $release_date
14 * @property Carbon $eol_date
15 */
16class LinuxDistro extends Model
17{
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}

The Migration

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(): void
13 {
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(): void
27 {
28 Schema::dropIfExists('linux_distros');
29 }
30};

Finally, to apply this migration, we need to run one more Artisan command.

php artisan migrate

Configure Scout and Meilisearch

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

Seeding Data

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 Seeder
10{
11 /**
12 * Run the database seeds.
13 */
14 public function run(): void
15 {
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

The Livewire Components

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.

The Livewire Controller

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' => $distros
20 ]);
21 }
22}

The Livewire View

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 @else
13 @if ($distros->hasMorePages())
14 <p>Showing {{ $distros->count() }} of {{ $distros->total() }} results.</p>
15 @endif
16 
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 @endforeach
25 @endif
26 </div>
27</div>

The Main View

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>

The Route

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');