# AlgoliaのInstantSearch.jsのCustom Widgetsを活用してQuery Suggestionsを表示する

このブログのタイトルだけ見ると、横文字だらけでAlgoliaの検索とか、InstantSearch.jsに馴染みの無い人にはなんのこっちゃ?っていう話なのですが(笑)、成果物的には👇こんな感じのイメージです。

検索バーに入力された内容を元に、クエリ文字列をサジェストしてくれる機能。Algoliaでは、この機能が有効になっていると(2020年7月からの新しい料金プランではStandardでもPremiumでもこの機能がついてきます)、Algoliaがクエリのログを元に裏側でサジェスト用のindexをやりくりしてくれて、検索バーに入力された文字列をメインのindexに加えてサジェスト用のindexにも連携してやることで上記のような体験を構築することが出来ます。

このように1つの検索バーの入力から複数のindexに同時にクエリを投げて結果を表示することをAlgoliaではfederated searchと呼んでいます。

例えば👇のBIRCHBOXはフランスのコスメ系のWebサイトですが、検索ボックスにキーワードを入力すると、プロダクト/ブランド/カテゴリ/記事という4つのインデックスにパラレルにクエリを投げて結果を表示しています。

birchbox

# InstantSearch.jsを使ってどうやってfederated searchを実装するか?

ちょうど良い題材というかUKにいる同僚の @MatthewFoyle がイイ感じのWebinarをやっていたので、この知恵を拝借させていただきました👇

ポイントは、メインのindexの検索結果と、Query Suggestionsのindexの検索結果のやりくりをInstantSearch.jsのCustom Widgetsを使って、本体のJavaScriptファイルの見通しを良くするというか、インデックスの設定とWidgetの追加だけにしてしまうというやり方。

# では、さっそくやっていきましょう

恐らく一番手っ取り早いのは npx create-instantsearch-app hoge-app みたいな感じでやっていく感じかな、と。

こちらの詳細は https://github.com/algolia/create-instantsearch-app を見てね〜という感じではあるのですが、InstantSearch.jsのGetting Startedガイドにも記載されているように、とりあえずテンプレートに従って、InstantSearch.jsが動くプロジェクトを作ってくれますよ、と。

で、 npm start すると localhost:3000 で動作が確認できるようになります。

# HTMLで指定されるJavaScript

上記のnpxで構築されたプロジェクトではindex.htmlの中で app.js というファイルが指定されていると思います。

<script src="https://cdn.jsdelivr.net/algoliasearch/3.32.0/algoliasearchLite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.7.0"></script>
<script src="./src/app.js"></script>

で、その中を見ると👇みたいな記述があったりして、これくらいシンプルなものだったら良いのかもしないのですが、何個もコレ系の記述が(例えば上記のBirchboxのように4個とか5個とか)続くと、あんまりコードの見通しがよくないのかな、と。

    templates: {
      item: `
<article>
  <h1>{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}</h1>
</article>
`,
    },

# Custom Widgetを使って外出しにする

👇のようにimportする形にして、QSHitsとProductHitsという外部ファイルで固有のロジックを実装することで、

import {index, searchBox, configure, refinementList} from 'instantsearch.js/es/widgets';
import {QSHits} from './QSHits.js';
import {productHits} from './ProductHits.js';

app.jsのaddWidgetsは👇こんな風にスッキリしたものになりました、と。

search.addWidgets([
  searchBox({
    container: '#searchbox',
  }),
  index({
    indexName: 'ranqueen.ninja_query_suggestions'
  }).addWidgets([
    configure({
      hitsPerPage: 16,
    }),
    QSHits({
      container: '#query-suggestions'
    })
  ]),
  configure({
    hitsPerPage: 4
  }),
  productHits({
    container: '#product-hits'
  }),
  refinementList({
    container: '#shop-refinement',
    attribute: 'shop_name',
    limit: 6
  })
]);

# カスタムウィジェットの作り方

今回は、Query Suggestionsのindexをクエリした結果のhitsをカスタマイズして表示したいわけですが、Algolia Documentationのhits - InstantSearch.jsによると、UIをカスタマイズしたい場合は connectHits を使いましょう、と👇

connectHits

今回QSHits.jsの中で行ってるのは👇のようにぐるぐる回した結果をrenderHitsという変数に突っ込んで、

const renderHits = (renderOptions, isFirstRender) => {
  const {hits, widgetParams} = renderOptions;

  document.querySelector(widgetParams.container).innerHTML = `
    <ul class="suggestions-lint">
      ${hits
        .map(
          item => 
            `<li class="suggestions-hit">
              ${instantsearch.highlight({attribute: 'query', hit: item})}
            </li>` 
        ).join('')}
    </ul>
  `;
};

connectHitsを使ってやることで、addWidgetsで使えるようになります、と。

export const QSHits = connectHits(renderHits)

# InstantSearch.jsには様々なWidgetがありますが、、

Widget一覧だったり、Widget Showcaseで様々なWidgetをご覧いただけますが、こういうの、腕に覚えのあるフロントエンド技術者の方だと、イイ感じのをサクっと作っていただけたりするのかな、、などと思いますが、Create Your Own Widgetsのページは👇のように

You are trying to create your own widget with InstantSearch.js and that’s awesome 🎉. But that also means that you couldn’t find the widgets or built-in options you were looking for. We’d love to hear about your use case as our mission with our InstantSearch libraries is to provide the best out-of-the-box experience. Don’t hesitate to send us a quick message explaining what you were trying to achieve either using the form at the end of that page or directly by submitting a feature request

InstantSearch.jsのウィジェットを作っていただくのは素晴らしいことだけど、InstantSearchを開発しているチームとしてはout-of-the-box(箱を開けてすぐの状態)に使えるライブラリを取り揃えていきたいと思っているので、もしよろしければ、xxxなWidgetが欲しかったけどありませんでした的なFeatureリクエストをいただけると嬉しいです、とのことでございます。

# Algoliaの新しい料金プラン

AlgoliaのStandardおよびPremiumプランでは、[Algolia Blog翻訳] Algoliaの新しい料金プランのご紹介に記載させていただきましたように、様々な機能がpay-as-you-goな形でご利用いただけるようになっていますし、もちろん日本語でも動作いたします。例えば https://ranqueen.ninja/https://www.yoshida.red/search.html をご覧いただければと思います。

今回ご紹介させていただいたQuery Suggestionsの他にも、PersonalizationやAnalyticsなど、今まで上位プランで且つ年間契約でしかご利用いただけなかったような機能をお気軽にお試しくださいませ。

何かAlgoliaで気になる点などございましたらTwitterの #AlgoliaJP に投稿いただければ幸いです。

このエントリーをはてなブックマークに追加

Algolia検索からの流入のみConversionボタン表示