Setup Algolia InstantSearch on Nuxt/Vue

Aug 19, 2020

I shall setup Algolia InstantSearch on client side only.

Install

npm install vue-instantsearch algoliasearch instantsearch.css

Setup

Create plugins/init-client.js

import Vue from 'vue'import InstantSearch from 'vue-instantsearch'Vue.use(InstantSearch)

Edit nuxt.config.js

export default {  // ...  plugins: [    // ...    { src: '~/plugins/init-client', mode: 'client' },    // ...  ],  // ...}

Usage

Create pages/search.vue. Replace

  • index-name (Under Indices in Algolia Dashboard)
  • Application ID (Under API Keys in Algolia Dashboard)
  • Search-Only API Key

A few changes are made

  • Prevent search/listing if there if no query
  • Show result in row instead of grid
  • Hide pagination if only 1 page of result
<template>
  <div>
    <client-only>
      <ais-instant-search
        :search-client="searchClient"
        index-name="live"
      >

        <ais-search-box />

        <ais-hits>
          <div slot="item" slot-scope="{ item }">
            <!-- show name -->
            <h2><ais-highlight attribute="name" :hit="item"/></h2>
            <!-- show content -->
            <div>{{ item.content }}</div>
            <!-- show content with highlight -->
            <div><ais-highlight attribute="content" :hit="item"/></div>
            <!-- show content with snippet: need to setup Snipetting in Indices -->
            <div><ais-snippet attribute="content" :hit="item"/></div>
          </div>
        </ais-hits>

        <ais-state-results>
          <template slot-scope="{ state: { query }, results: { hits, nbPages } }">
            <!-- show no result if query with no hits -->
            <div v-if="query && hits.length == 0">No results</div>
            <div v-else></div>

            <!-- hide pagination if 1 or less pages -->
            <ais-pagination v-if="nbPages > 1"/>
          </template>
        </ais-state-results>

      </ais-instant-search>
    </client-only>
  </div>
</template>

<script>
import algoliasearch from 'algoliasearch/lite'
import 'instantsearch.css/themes/algolia-min.css'
// import 'instantsearch.css/themes/reset-min.css'


const algoliaClient = algoliasearch(
  '3P********', // Application ID
  '0a5f4c5c0b18********************'  // Search-Only API Key
)

// this setup is required to prevent search on empty query
const searchClient = {
  search(requests) {
    if (requests.every(({ params }) => !params.query)) {
     return Promise.resolve({
        results: requests.map(() => ({
          hits: [],
          nbHits: 0,
          nbPages: 0,
          processingTimeMS: 0,
        })),
      });
    }

    return algoliaClient.search(requests);
  },
};


export default {
  data() {
    return {
      /*
      searchClient: algoliasearch(
        '3P********', // Application ID
        '0a5f4c5c0b18********************'  // Search-Only API Key
      ),
       */
      searchClient
    }
  },
};
</script>

<style>
/* add bottom margin to search box */
.ais-SearchBox {
  margin-bottom: 1em;
}

/* change search result from grid/box to row */
.ais-Hits-item {
  width: 100%;
  border: none;
  box-shadow: none;

}

/* prevent highlight overwrite font-size */
.ais-Highlight {
  font-size: inherit;
}
.ais-Highlight-highlighted {
  font-size: inherit;
}
</style>

More

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.