Integrating Typesense with Laravel Scout (And The Mistake That Wasted My Time)
After setting up Typesense on my own servers, the next step was connecting it to Laravel using Laravel Scout. Laravel Scout makes searching models super easy, but I ran into a frustrating issue that wasted a lot of my time.
In this post, I’ll walk you through how I set it up and the mistake I made (so you don’t have to make it too!).
First, I installed Laravel Scout and the Typesense PHP package:
composer require typesense/typesense-php
Then, set the SCOUT_DRIVER
environment variable as well as your Typesense host and API key credentials within your application's .env file:
SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost
Then, I published the Scout configuration file:
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
In my User model (app/Models/User.php
), I added the Searchable trait:
use Laravel\Scout\Searchable;
class User extends Model
{
use Searchable;
}
Then, I defined what should be indexed by overriding toSearchableArray()
:
public function toSearchableArray(): array
{
return [
'id' => (string) $this->id,
'email' => (string) $this->email,
'created_at' => $this->created_at->timestamp,
];
}
Everything looked perfect but when I tried to sync the database with Typesense, it didn’t work.
When I ran:
php artisan scout:import App\\Models\\User
I got this annoying error:
{
"error": "Parameter `fields` is required."
}
At first, I was confused. I had already specified what should be indexed in toSearchableArray()
—so why was it complaining?
After checking Typesense logs, Laravel logs, and even googling for hours, I finally found the issue.
In my config/scout.php
file, I had forgotten to include this line at the top:
use App\Models\User;
and that was because of this User::class in the scout.php config
'model-settings' => [
User::class => [
'collection-schema' => [
'fields' => [
['name' => 'id', 'type' => 'string'],
['name' => 'name', 'type' => 'string'],
['name' => 'created_at', 'type' => 'int64'],
],
'default_sorting_field' => 'created_at',
],
'search-parameters' => [
'query_by' => 'email',
],
],
Without this, Laravel didn’t know which model to apply the settings to.
Once I added that line and re-ran the command, everything worked perfectly!
Now, I could search for users instantly