In this article, we will see how to live search in laravel 9 using Meilisearch. Here we will learn live search in laravel 9 using livewire and Meilisearch. So, we will create a custom search in laravel 9. Meilisearch is an open-source, lightning-fast, and hyper-relevant search engine that fits effortlessly into your apps, websites, and workflow. Meilisearch is plug and play and flexible plugin.
Also, we will install laravel livewire in the application and create a full-text search in laravel 9. You can customize the meilisearch as per requirements.
So, let's see the search using livewire and meilisearch in laravel 9.
Step 1: Install Laravel 9
Step 2: Install Laravel Breeze
Step 3: Create Model and Migration
Step 4: Create Database Seeder
Step 5: Install Livewire
Step 6: Create Component
Step 7: Install Laravel Scout
Step 8: Create Blad File
In this step, we will install laravel 9 using the following command.
composer create-project laravel/laravel laravel9_live_search
Now, we will install laravel breeze using the following command.
composer require laravel/breeze
After that, we will create a migration and model using the following command.
php artisan make:model Articles -m
app/Models/Articles.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Articles extends Model
{
use HasFactory;
protected $fillable = [
'title', 'author', 'description'
];
}
Migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('author');
$table->longText('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('articles');
}
};
In this step, we will create dummy records using a factory. So, we will create ArticleFactory using the following command.
php artisan make:factory ArticleFactory
database/factories/ArticlesFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Articles>
*/
class ArticlesFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'title' => $this->faker->words(4, true),
'author' => $this->faker->name(),
'description' => $this->faker->sentence()
];
}
}
database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\Articles;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
Articles::factory(50)->create();
}
}
Now, run the database seeder using the following command.
php artisan db:seed
In this step, we will install laravel livewire using the following command.
composer require livewire/livewire
After that, we will include @livewirestyles and @livewirescripts to the app.blade.php file
resources/views/components/app.blade.php
<!DOCTYPE html>
<html>
<head>
<title>How To Live Search In Laravel 9 Using Meilisearch - Websolutionstuff</title>
@livewireStyles
</head>
<body>
</body>
@livewireScripts
</html>
Now, we will create a livewire component using the following command.
php artisan make:livewire Articles
Then, we will include the Article component in the dashboard.blade.php file.
resources/views/dashboard.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
@livewire('articles')
</div>
</div>
</div>
</div>
</x-app-layout>
In this step, we will install the laravel scout package using the composer command.
composer require laravel/scout
Then, we can publish the configurations.
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
Laravel Scout allows us to use any search driver such as database, algolia or meilisearch, etc.
Now, we will include the laravel scout searchable trait in the Article model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable; //import the trait
class Articles extends Model
{
use HasFactory;
use Searchable; //add this trait
protected $fillable = [
'name', 'author', 'description'
];
}
After that, we will install the factory HTTP guzzle using the following command.
composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
Then, we can set the environment variables for the use of Meilisearch.
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey
Then, we need to index our records in meilisearch using the scout:import command.
php artisan scout:import "App\Models\Articles"
app/Livewire/Articles.php
<?php
namespace App\Http\Livewire;
use App\Models\Articles as ModelsArticles;
use Livewire\Component;
class Articles extends Component
{
public $search = '';
public $articles;
public function render()
{
if (empty($this->search)) {
$this->articles = ModelsArticles::get();
} else {
$this->articles = ModelsArticles::search($this->search)->get();
}
return view('livewire.articles');
}
}
Now, we will create an article.blade.php file and add the input field to that file. Using the wire:model property, we can pass the query onto the server and get the results back synchronously.
resources/view/livewire/articles.blade.php
<div>
<!-- component -->
<link rel="stylesheet" href="https://demos.creative-tim.com/notus-js/assets/styles/tailwind.css">
<link rel="stylesheet" href="https://demos.creative-tim.com/notus-js/assets/vendor/@fortawesome/fontawesome-free/css/all.min.css">
<section class="py-1 bg-blueGray-50">
<div class="w-full xl:w-8/12 mb-12 xl:mb-0 px-4 mx-auto mt-24">
<div class="relative flex flex-col min-w-0 break-words bg-white w-full mb-6 shadow-lg rounded ">
<div class="rounded-t mb-0 px-4 py-3 border-0">
<div class="flex flex-wrap items-center">
<div class="relative w-full px-4 max-w-full flex-grow flex-1">
<h3 class="font-semibold text-base text-blueGray-700">Articles</h3>
</div>
<div class="relative w-full px-4 max-w-full flex-grow flex-1 text-right">
<input type="text" placeholder="Search..." wire:model="search">
</div>
</div>
</div>
<div class="block w-full overflow-x-auto">
<table class="items-center bg-transparent w-full border-collapse ">
<thead>
<tr>
<th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
Article name
</th>
<th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
Description
</th>
<th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
Author
</th>
</thead>
<tbody>
@if (!$articles->isEmpty())
@foreach ($articles as $article)
<tr>
<th class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4 text-left text-blueGray-700 ">
{{$article->title}}
</th>
<td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4 ">
{{$article->description}}
</td>
<td class="border-t-0 px-6 align-center border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
{{$article->author}}
</td>
</tr>
@endforeach
@else
<td class="border-t-0 px-6 align-center border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
No Results Found
</td>
@endif
</tbody>
</table>
</div>
</div>
</div>
</section>
</div>
Output:
You might also like: