Integrations / Frameworks / Laravel / Getting Started With Laravel Scout and Vue Instant Search
Apr. 18, 2019

Getting Started With Laravel Scout and Vue Instant Search

Introduction

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 greatly simplifies the use of Algolia’s InstantSearch library. This tutorial will show you how to benefit from both of these features.

Let’s get started. We’ll assume you have a fresh Laravel application, and that the model you want to index is Contact. A contact has: a name, an email, a company and a state. We’ll provide the data.

The tutorial is split into 4 steps:

  1. Create the model class and seed the database
  2. Install Scout, then Index your data
  3. Install Vue InstantSearch
  4. 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 will create a model class in src/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 dummy data

Now you’ll want to import data from one of Algolia’s datasets. Download the dataset here and place it at the root of your resources folder.

Let’s create a seeder class so that you can select what data to import.

1
php artisan make:seeder ContactSeeder

Laravel generated a new database/seeds/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
<?php

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 will open the JSON file holding your dummy data and push what you need into the database. After this command, you’re good to go!

1
php artisan db:seed --class=ContactSeeder

Install Laravel Scout

Now you need to install Scout and Algolia’s API client via composer.

1
2
composer require laravel/scout
composer require algolia/algoliasearch-client-php:^2.2

If you use a 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,

Run the following command to finish the installation. It will add a new scout.php file to your config folder.

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’ll find 3 important pieces of information there:

  • Your application ID
  • Your search-only API key
  • Your admin API key

You’ll want to put these in your .env file. We recommend not putting them directly in config/scout.php because they shouldn’t be versioned.

1
2
3
4
5
ALGOLIA_APP_ID=YourApplicationID
ALGOLIA_SECRET=YourAdminAPIKey

MIX_ALGOLIA_APP_ID=YourApplicationID
MIX_ALGOLIA_SEARCH=YourSearchOnlyAPIKey

Index your data

Laravel Scout provides an easy way to index your data: all you need to do is add a trait to your model. This trait will add a few functionalities to the default model class, including keeping your data in sync with Algolia.

Open up your src/Contact.php file and add the Laravel/Scout/Searchable trait.

1
2
3
4
5
6
7
8
9
10
<?php
namespace App;

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'

That’s it! Take a look at your dashboard and you should be able to see your data.

Setup Vue.js

At Algolia, we advocate frontend search, which gives your users instant results, and also frees up your server from processing every search request. We’ll explain how you can do this with the Vue version of our InstantSearch library.

We wrote Vue InstantSearch to save you a lot of time. We didn’t think you should have to write a lot of boilerplate JavaScript to do the basics of frontend search, such as formatting data, querying Algolia, handling pagination, displaying facets and filtering, and many other common UI features.

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
import VueInstantSearch from 'vue-instantsearch';
Vue.use(VueInstantSearch);

Build your search experience

Compiling js

To compile the js into the app.js bundle file we need to run:

1
npm run watch

This will make sure that every time we change one of the javascript file it rebuilds our assets.

Defining where Vue renders

In a default Laravel app, Vue renders inside an #app tag.

1
<div id="app"></div>

To make things simpler, we can use a new file 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>

Note: To make your life easier, we recommend using the Vue.js devtools.

We can also add the default theming at the same time, by importing it in scss/app.scss

1
@import '~instantsearch.css/themes/algolia-min';

Using components

Every component provided by InstantSearch needs to be enclosed in an <ais-instant-search> tag. It lets the library know how to contact Algolia servers. We 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
21
22
23
<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
5
6
7
<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 components only show the ID of the result. You can pass a template to have your contact displayed nicely.

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
<ais-hits>
  <template
    slot="item"
    slot-scope="{ 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>

That’s it!

Conclusion

We recommend you implement your search on the front-end search. InstantSearch makes it fast and easy to do.

InstantSearch is also available for React, Angular, and in a framework-agnostic version.

There is much more to learn. We recommend checking out these links to learn more about Laravel and Algolia:

Did you find this page helpful?