Getting started with Laravel Scout and Vue InstantSearch
This tutorial was written for Laravel 8. It doesn’t work with newer versions of Laravel.
Integrating Algolia into Laravel has just gotten easier with the addition of Laravel Scout and the bundling of Vue JS. While Scout seamlessly wraps the Algolia engine, the Vue JS bundle simplifies the use of Algolia’s InstantSearch library.
For this tutorial, you need a fresh Laravel application. You’ll index a Contact
model, which holds a name, an email, a company and a state.
The tutorial consists of 4 steps:
- Create the model class and seed the database
- Install Scout, then index your data
- Install Vue InstantSearch
- Build your search experience
Create the model
Create an empty model and a migration file with the corresponding artisan
command.
1
php artisan make:model -m Contact
This creates a model class in app/Contact.php
and a migration in database/migrations/DATE_create_contacts_table.php
.
Edit this migration file so it looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateContactsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->string('company')->nullable();
$table->string('state')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('contacts');
}
}
Now that your Laravel app knows what a contact is, you can migrate the database to reflect these changes.
1
php artisan migrate
Import your fake data
Now you need to import data from Algolia’s contacts dataset and place it at the root of your resources
folder.
Create a seeder class so that you can select what data to import.
1
php artisan make:seeder ContactSeeder
Laravel generated a new database/seeders/ContactSeeder.php
file. Open it up and edit it to add the following class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class ContactSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$contacts = [];
$raw = json_decode(
file_get_contents(resource_path('contacts.json')),
true
);
foreach ($raw as $contact) {
$contacts[] = [
'name' => $contact['firstname'].' '.$contact['lastname'],
'email' => $contact['email'],
'company' => $contact['company'],
'state' => $contact['state'],
];
}
DB::table('contacts')->insert($contacts);
}
}
This class opens the JSON dataset and pushes what you need into the database. You can now seed your database:
1
php artisan db:seed --class=ContactSeeder
Install Laravel Scout
Install Laravel Scout and Algolia’s API client using composer.
1
2
composer require laravel/scout
composer require algolia/algoliasearch-client-php:^2.2
If you use a Laravel version older than 5.5, add the service provider class name to the providers
array in the config/app.php
file. If you use Laravel 5.5 or higher, you can skip this step.
1
Laravel\Scout\ScoutServiceProvider::class,
Create a scout.php
file in your config
folder with the following command:
1
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
Configure Algolia’s credentials
Head to your Algolia dashboard and go to the API keys section. You can find 3 important pieces of information there:
- Your application ID
- Your search-only API key
- Your admin API key
You need to put these in your .env
file. Don’t put these credentials directly in your config/scout.php
file, they shouldn’t be part of your version history.
1
2
3
4
5
ALGOLIA_APP_ID=YourApplicationID
ALGOLIA_SECRET=YourWriteAPIKey
MIX_ALGOLIA_APP_ID=YourApplicationID
MIX_ALGOLIA_SEARCH=YourSearchOnlyAPIKey
Index your data
Laravel Scout provides a convenient way to index your data: all you need to do is add a trait to your model. This trait adds functionalities to the default Model
class, including keeping your data in sync with Algolia.
Open up your app/Contact.php
file and add the Laravel/Scout/Searchable
trait.
1
2
3
4
5
6
7
8
9
10
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Contact extends Model
{
use Searchable;
}
Before you can keep your data in sync, you need to perform a batch import the first time. Scout has added a command for this.
1
php artisan scout:import 'App\Contact'
Take a look at your dashboard and you should be able to see your data.
Setup Vue.js
It’s recommended to use frontend search, which gives your users instant results, and also frees up your server from processing every search request.
You can use the Vue InstantSearch
library to create a frontend search without writing a lot of boilerplate JavaScript to handle complex search behaviors.
Install Vue InstantSearch
Since Laravel ships with Vue by default, you have nothing to setup. You’ll only need to add vue-instantsearch
as a dependency with npm and register it as a Vue plugin.
1
npm install vue-instantsearch algoliasearch instantsearch.css
Then, open up your resources/js/app.js
and add the following line just after the window.Vue = require('vue');
line.
1
2
3
import VueInstantSearch from 'vue-instantsearch';
Vue.use(VueInstantSearch);
Build your search experience
Compiling JavaScript code
To compile the JavaScript into the app.js
bundle file, run the following command:
1
npm run watch
This rebuilds your assets every time you change one of the JavaScript files.
Defining where Vue renders
In a default Laravel app, Vue renders inside an #app
tag.
1
<div id="app"></div>
Create a new file in your components
directory called MySearch.vue
and register it in app.js
for the search interface:
1
Vue.component('my-search', require('./components/MySearch.vue').default)
Then update the blade view, adding the my-search
component:
1
2
3
4
<div id="app">
<my-search />
</div>
<script src="{{ mix('js/app.js') }}"></script>
You can use vue-devtools
to debug your Vue components.
You can use InstantSearch’s default theming by importing it in scss/app.scss
.
1
@import '~instantsearch.css/themes/algolia-min';
Using InstantSearch components
Every InstantSearch component needs to be inside an <ais-instant-search>
tag. This lets the library know how to contact Algolia servers. You can set this up in MySearch.vue
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<ais-instant-search :search-client="searchClient" index-name="contacts">
<!-- Other search components go here -->
</ais-instant-search>
</template>
<script>
import algoliasearch from 'algoliasearch/lite'
export default {
data() {
return {
searchClient: algoliasearch(
process.env.MIX_ALGOLIA_APP_ID,
process.env.MIX_ALGOLIA_SEARCH
),
}
},
}
</script>
The library provides ready to use components to add a search bar and display the results.
1
2
3
4
<ais-instant-search :search-client="searchClient" index-name="contacts">
<ais-search-box placeholder="Search contacts..."></ais-search-box>
<ais-hits></ais-hits>
</ais-instant-search>
By default, the component just shows the ID of the results. You can pass a template to change how your results display.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<ais-hits>
<template v-slot:item="{ item }">
<h1>
<ais-highlight
:hit="item"
attribute="name"
/>
</h1>
<h4>
<ais-highlight
:hit="item"
attribute="company"
/> -
<ais-highlight
:hit="item"
attribute="state"
/>
</h4>
<ul>
<li>{{ item.email }}</li>
</ul>
</template>
</ais-hits>
Conclusion
It’s recommended to create a frontend search using InstantSearch. InstantSearch is also available for React, Angular, and in a framework-agnostic version.
There is much more to learn. Check out these links to learn more about Laravel and Algolia: