Algolia の InstantSearch.js を使った Shifter Static と Shifter Headless の Federated Search

こちらは Shifter Advent Calendar 2020 の 2日目の記事になります!


9月に開催されたShifterさんのMeetupでAlgoliaのご紹介をさせていただきましたが、その際に↓のスライドの38ページのように、

例えば、Shifter Headlessで作ったインターネットショッピングサイトと、Shifter Staticで作ったブログサイトを横断して検索するといったところをご紹介させていただきました。

今回は実際にこの構成の簡易版のようなものを作ってみたいと思います。

Shifter Staticの立ち上げ

まずはShifter StaticでWordPressのブログをPublishしてみます。

見慣れたWordPressのDashboard上で記事を4つほど記事を書きました。

Algoliaのプラグインを入れていきます。

Algoliaにデータが入ったら、日本語の設定を入れていきます。

まだダッシュボードではサポートされていませんが、Transliterationの設定を入れていきます。これによって平仮名でカタカナや漢字の言葉を検索できるようになります。こちらまだベータ機能ではございますが、設定項目としては↓で、配列で対象attributeを指定するものになりますが、今回はアスタリスクで全ての属性を対象にしてみました。

attributesToTransliterate: ["*"]

そんなこんなでAlgoliaへのIndexingは完了。

Shifter Staticでブログサイトも出来ました。

Shifter Headlessの立ち上げ

とりあえずHeadlessの方もポチポチやって立ち上げてWordPressのダッシュボードが表示されて、デフォルトのテーマが見れるところまでやりました。

Headlessの方でも4つ記事を書きました。

Headlessの方でもプラグインを使ってAlgoliaにデータを突っ込んでいきます。

ということで、コレでShifter StaticとShifter Headlessの両方のコンテンツをAlgoliaに投入することが出来ました。

WordPress REST APIでShifter Headlessからデータを取得

上記のデータを使って、ローカルでFederated Searchな検索を作って『ハイ、おしまい』では寂しいので、今回は WordPress REST API Sample App をやってみたいと思います 🙂

Introducing Shifter Headless の Fetch and display contents にあるように、まずは WordPress REST API Sample App repository を git clone してきます。

$ git clone https://github.com/smartcatdev/WordPress-REST-API-Sample-App  
Cloning into 'WordPress-REST-API-Sample-App'...
remote: Enumerating objects: 60, done.
remote: Total 60 (delta 0), reused 0 (delta 0), pack-reused 60
Unpacking objects: 100% (60/60), done.

WordPress-REST-API-Sample-App/includes/app/main.js を開いて、URLを変更します。

そうすると↓のようにShifter HeadlessのWordPressに突っ込んだデータがローカルで参照できるようになりました!

Shifter Static と Shifter Headless の Federated Search

それでは、このローカルで動いているindex.htmlにAlgoliaのInstantSearch.jsでFederated Searchを構築していきましょう!

まずはheadの中でCSSの読み込み

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7.1.0/themes/algolia.css" />

トップバーの下にInstantSearch.js用のdivを定義

        <div class="container">
            <h1>InstantSearch.js で 複数のIndexからデータ取得</h1>
            <div id="searchbox"></div>
        
            <h2>index: Shifter Static</h2>
            <div id="hits-static"></div>
        
            <h2>index: Shifter Headless</h2>
            <div id="hits-headless"></div>
        </div>

bodyの最後でInstantSearch.jsのJavaScriptを読み込み(app.jsがInstantSearch.jsでコードを書いていくファイル)

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

それではInstantSearch.jsを使ってコードを書いていきます(といっても、Algolia検索用のオブジェクトをイニシャライズして、Widgetを足していくだけなのですが…笑)

・イニシャライズ(Algolia IndexはHeadlessの方を指定)

const searchClient = algoliasearch(
  'アプリケーションID',
  'Search-Only API Key'
);

const search = instantsearch({
  indexName: 'headless_searchable_posts',
  searchClient,
});

・Widgetの設定。

  1. 上から順番に 1ページにつき何件まで表示するか
  2. 検索ボックス&ボックス内に表示するプレースホルダ
  3. Powered Byの表示
  4. 取得したHeadlessのデータの表示
search.addWidgets([
  instantsearch.widgets.configure({
    hitsPerPage: 3,
  }),

  instantsearch.widgets.searchBox({
    container: '#searchbox',
    placeholder: 'Shifter x Algolia Search'
  }),

  instantsearch.widgets.poweredBy({
    container: '#powered-by',
  }),

  instantsearch.widgets.hits({
    container: '#hits-headless',
    templates: {
      item:`
        {{#helpers.highlight}}{ "attribute": "post_title" }{{/helpers.highlight}}
        <p>{{ content }}<p>
        `,
    },
  }),

・続いてStaticの方のIndexとhits Widgetの設定

上記の続きに別のIndexの定義をしてあげるだけ。1ページに3件ずつで、hitsウィジェットをstatic用のdivに。Headlessの方も同様ですが、templatesのところは思いっきりデザイン的により良くする方法はあるのかと存じます。笑

  instantsearch.widgets
    .index({ indexName: 'shifter_searchable_posts' })
    .addWidgets([
      instantsearch.widgets.configure({
        hitsPerPage: 3,
      }),

      instantsearch.widgets.hits({
        container: '#hits-static',
        templates: {
          item: `
          {{#helpers.highlight}}{ "attribute": "post_title" }{{/helpers.highlight}}
          <p>{{ content }}<p>
          `,
        },
      }),
    ]),
]);

成果物

それっぽいのが出来たかなと思います 🙂

せっかくなのでQuickTimeで画面の動画を収録してmp4に変換してTwitterにあげてみました。

AlgoliaのAdvent Calendarもよろしくお願い致します!

AlgoliaのAdvent Calendar 2020はコチラです👉 Algolia Advent Calendar 2020

(このままだと私がAlgolia日記みたいのを書き連ねることになってしまうかもしれません。笑)

コメント

タイトルとURLをコピーしました