Working with Autocomplete


You can combine the power of Miso with InstantSearch.js and Autocomplete.

  1. Install Miso SDK and its Algolia plugin.
  2. Install Autocomplete.
  3. Follow the guide to integrate InstantSearch.js and Autocomplete.
  4. Use the autocomplete client from Miso in place of Algolia's original search client.

Live demo

Example

Setup InstantSearch:

const client = new MisoClient('...');
const indexName = ''; // empty string for your default Miso engine

const search = instantsearch({
  // use Miso's search client
  searchClient: client.algolia.searchClient(),
  indexName: indexName
});

search.addWidgets([
  instantsearch.widgets.configure({
    hitsPerPage: 8
  }),
  // remove the original search box widget
  /*
  instantsearch.widgets.searchBox({
    container: '#search-box',
    autofocus: true,
    searchAsYouType: false,
    showSubmit: true,
  }),
  */
  // mount a virtual search box to manipulate InstantSearch's `query` UI state parameter
  instantsearch.connectors.connectSearchBox(() => {})({}),
  instantsearch.widgets.hits({
    container: '#hits',
    templates: { /* ... */ }
  })
]);

search.start();

Make a tool function to sync Autocomplete's query to InstantSearch's query state:

function setInstantSearchQueryState(query = '') {
  search.setUiState(uiState => ({
    ...uiState,
    [indexName]: {
      ...uiState[indexName],
      page: 1,
      query: query
    }
  }));
}

Setup Autocomplete:

autocomplete({
  container: '#autocomplete',
  initialState: {
    query: ''
  },
  onSubmit: ({ state }) => {
    setInstantSearchQueryState(state.query);
  },
  onReset: () => {
    setInstantSearchQueryState();
  },
  /*
  // for a submit-based search paradigm, comment out this part
  onStateChange: ({ prevState, state }) => {
    const { query: prevQuery } = prevState;
    const { query } = state;
    if (prevQuery !== query) {
      setInstantSearchQueryState(query);
    }
  },
  */
  autoFocus: true,
  getSources: ({ query }) => {
    // this is triggered on every user input
    return [{
      getItems: () => getAlgoliaResults({
        // use Miso's autocomplete client
        searchClient: client.algolia.autocompleteClient(),
        queries: [{
          query: query,
          params: {
            hitsPerPage: 5,
            attributesToHighlight: ['suggested_queries'],
          }
        }]
      }),
      onSelect: ({ setQuery, item }) => {
        const query = item._text;
        setQuery(query);
        setInstantSearchQueryState(query);
      },
      templates: {
        item: ({ item, components, html }) => html`
          <div class="aa-ItemWrapper">
            <div class="aa-ItemContent">
              <div class="aa-ItemContentBody">
                <div class="aa-ItemContentTitle">
                  ${components.Highlight({
                    hit: item,
                    attribute: 'suggested_queries',
                  })}
                </div>
              </div>
            </div>
          </div>
        `
      }
    }];
  }
});