Guides / Building Search UI

Welcome to InstantSearch.js

InstantSearch.js is a vanilla JavaScript library that lets you create an instant search results experience using Algolia’s search API.

This guide shows you how to build a search UI for an ecommerce website, including:

  • Bootstrapping an InstantSearch.js app with Algolia’s command-line utility create-instantsearch-app
  • Displaying and formatting the search bar and results
  • Using pre-built UI components (widgets) to filter results

Your goal is to create a fully working InstantSearch.js app as fast as possible. This guide provides you with the data, installation instructions, a step-by-step process, and all the necessary code. It doesn’t cover how everything is “wired together”, but you can dig into the library afterward.

A live demonstration

Here’s what you can build in a couple of minutes:

If you haven’t done so yet, take a look at the two-minute interactive getting started tutorial.

Building a UI

Bootstrap your application

To bootstrap a working InstantSearch.js app in seconds, use the create-instantsearch-app command-line tool.

Open a terminal and paste these lines:

1
2
3
4
5
6
npx create-instantsearch-app ais-ecommerce-demo-app \
  --template "InstantSearch.js" \
  --app-id "B1G2GM9NG0" \
  --api-key "aadef574be1f9252bb48d4ea09b5cfe5" \
  --index-name demo_ecommerce \
  --attributes-to-display name

This generates a folder on your machine that looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
ais-ecommerce-demo-app/
├── node_modules
├── src
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── favicon.png
├── index.html
├── manifest.webmanifest
├── package.json
└── README.md

Your application uses predefined credentials (application ID, API key and index name) provided as part of this guide.

You can use create-instantsearch-app to generate any flavor of InstantSearch. The tool provides various options: read more about it on GitHub.

If you have a pre-existing JavaScript application, you can install InstantSearch.js as an npm package. See the installation guide for details.

Add the search UI code

Open the file index.html, remove the header and replace the div.container with:

1
2
3
4
5
6
7
8
9
<div class="ais-InstantSearch">
  <h1>InstantSearch.js e-commerce demo</h1>

  <div class="right-panel">
    <div id="searchbox"></div>
    <div id="hits"></div>
    <div id="pagination"></div>
  </div>
</div>

Then, open the file src/app.css and replace its content with:

1
2
body { font-family: sans-serif; padding: 1em; }
.ais-SearchBox { margin: 1em 0; }

Run your project

Now that you have bootstrapped the project and added the search UI code, you can run it and see what it looks like. Inside your terminal, type:

1
2
cd ais-ecommerce-demo-app
npm start

Then open your browser and navigate to http://localhost:3000, to see:

Getting started 1

You just bootstrapped an InstantSearch UI in no time. Now, dig into the code.

Dig in and understand the code

You can see in src/app.js that you are given your Algolia credentials to instantsearch() and you are using three InstantSearch widgets:

  • searchBox displays a nice looking Search Box for users to type queries
  • hits displays the results from Algolia, based on the query
  • pagination implements paging logic

There are a lot more widgets, you can discover them all in the widget showcase.

Additionally, you can see that widgets have a predefined style. Read more about this in the styling guide.

Add more widgets

To make your search UI more efficient and practical for your users, add some more widgets:

  • A way to filter results by brands
  • A way to clear active filters
  • A way to configure default search parameters

You first need to update the markup in index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="ais-InstantSearch">
  <h1>InstantSearch.js e-commerce demo</h1>

  <div class="left-panel">
    <div id="clear-refinements"></div>

    <h2>Brands</h2>
    <div id="brand-list"></div>
  </div>

  <div class="right-panel">
    <div id="searchbox"></div>
    <div id="hits"></div>
    <div id="pagination"></div>
  </div>
</div>

Open the file src/app.js, and add widgets to these placeholders:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// After the `searchBox` widget
search.addWidgets([
  instantsearch.widgets.clearRefinements({
    container: '#clear-refinements',
  }),

  instantsearch.widgets.refinementList({
    container: '#brand-list',
    attribute: 'brand',
  }),

  instantsearch.widgets.configure({
    hitsPerPage: 8
  }),
]);

Here are the new widgets you added:

This example uses configure to set the number of hitsPerPage to eight, but you can use this widget for any other search parameters such as filters, analytics.

The configure widget is renderless, it doesn’t output anything to the DOM.

To create a two-column layout, open the file src/app.css and update it:

1
2
3
4
5
body { font-family: sans-serif; padding: 1em; }
.ais-SearchBox { margin: 1em 0; }
.ais-Pagination { margin-top: 1em }
.left-panel { float: left; width: 250px; }
.right-panel { margin-left: 260px; }

Go to your browser, and refresh the page to see:

Getting started 2

Well done. You just added a bunch of widgets to your InstantSearch page.

Customize hits and add some final touches

The search UI is almost complete. The last step is to customize the rendering of the hits to display more information than just the name of the products.

Add more information

Open the file src/app.js and replace the content of the hits widget with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
search.addWidgets([
  instantsearch.widgets.hits({
    container: '#hits',
    templates: {
      item: `
        <div>
          <img src="{{image}}" align="left" alt="{{name}}" />
          <div class="hit-name">
            {{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}
          </div>
          <div class="hit-description">
            {{#helpers.highlight}}{ "attribute": "description" }{{/helpers.highlight}}
          </div>
          <div class="hit-price">\${{price}}</div>
        </div>
      `,
    },
  })
]);

Add some formatting

Open the file src/App.css and replace its content with:

1
2
3
4
5
6
7
8
9
10
11
body { font-family: sans-serif; padding: 1em; }
.ais-ClearRefinements { margin: 1em 0; }
.ais-SearchBox { margin: 1em 0; }
.ais-Pagination { margin-top: 1em; }
.left-panel { float: left; width: 250px; }
.right-panel { margin-left: 260px; }
.ais-InstantSearch { max-width: 960px; overflow: hidden; margin: 0 auto; }
.ais-Hits-item { margin-bottom: 1em; width: calc(50% - 1rem); }
.ais-Hits-item img { margin-right: 1em; }
.hit-name { margin-bottom: 0.5em; }
.hit-description { color: #888; font-size: 14px; margin-bottom: 0.5em; }

Now open your browser to see:

Getting started 3

Summary

You just learned how to customize the rendering of the Hits widget. Learn more about customization in the customization guide.

Learn how to configure the dataset

Then, you can configure the index using the following code:

1
2
3
4
5
6
7
8
9
10
11
12
// composer autoload
require __DIR__ . '/vendor/autoload.php';

// if you are not using composer
// require_once 'path/to/algoliasearch.php';

$client = \Algolia\AlgoliaSearch\SearchClient::create(
  'YourApplicationID',
  'YourAdminAPIKey'
);

$index = $client->initIndex('your_index_name');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$index->setSettings(array(
  "searchableAttributes" => [
    "brand",
    "name",
    "categories",
    "unordered(description)"
  ],
  "customRanking" => [
    "desc(popularity)"
  ],
  "attributesForFaceting" => [
    "searchable(brand)",
    "type",
    "categories",
    "price"
  ]
));

Did you find this page helpful?