ブログやサービスを作っていると、往々にして検索機能が欲しくなる事があります。
いざ実装しようとするとどの部分に検索をかけるか、部分一致検索にするか完全文字一致にするか…などなど意外とめんどくさい作業ですよね 😅
そんな中、Algoliaは検索に特化したサービスです!
検索機能を自身のサービスに簡単に実装する事が出来ますし、
しかも色んな言語やフレームワークをサポートしています。
Algolia公式ページより引用
フロントであれば今時のReactやVue、バックエンドはRubyにPythonと幅広く対応しています!
実際にどのようなサービスかについては公式の動画があるんですが、
それ以上に公式サイトのWidgetページを見ると、出来る事のイメージがしやすいです。
Widgets Showcase | Vue InstantSearch | Building Search UI | Guide | Algolia Documentation
ここではNuxt.jsにAlgoliaを導入します。
Nuxt ContentというNuxtでブログなどSSGを作るのに特化したライブラリ上での解説ですが、Nuxt.jsで作った場合と差異はないはず。
検証した環境
1 | nuxt | 2.14.12 |
2 | @nuxt/content | 1.11.1 |
前準備
料金について
料金は0円からスタート可能です
↑の公式のPRICINGページに書かれているように1ヶ月に10,000検索(10UNIT = 10 x 1,000検索)までは無料でいけます。
とりあえず試してみて、検索ボリュームと利便性から費用対効果を考えて判断する、というのでも良さそうです。
アカウント登録
アカウント登録はこのようなサービスなのでGitHubも選択出来るのは嬉しいところ!
名前や会社の情報を入力して作成、特に迷うところはなし。
またアカウント作成時にクレジットカードの登録は不要です。
気付いたら支払わないといけない、、といった心配をしなくて済むので安心ですね 😊
Algoliaの設定
まずAlgoliaで大きく3つの設定をします。
- indexの作成(検索対象1つにつき、1つのindexを作成)
- 検索するための元となるデータを設定
- 検索対象のリストを作成(重み付けも合わせて)
1. indexの作成
検索する対象に対して1つのindexを作成します。
To handle indices across multiple environments, just prefix/suffix your index name like dev_NAME, test_NAME, or prod_NAME
複数の環境でインデックスを処理するには、dev_NAME、test_NAME、prod_NAMEなどのインデックス名のプレフィックス/サフィックスを付けるだけです(Google翻訳)
と作成時に表示されるので、
dev_
・prod_
のようにprefix/suffixをつければ自動的に開発用、本番用といった差異を自動判別してくれる- 開発用、本番用など環境毎に違うデータを試したい場合は違うindexを作る必要がある
という事が分かります。
2. 検索するための元となるデータを設定
検索するためのデータを追加します。
追加方法は
- API経由でAlgoliaにアップロード
- JSONファイルをローカルで作成してAlgoliaにアップロード
- Algolia上で入力
の3つ。
私の場合ブログのため、
masterマージされたのをフック → CIでAPIを叩いて検索用のJSONをAlgoliaに自動アップロード
というのが最終目標ですが、今は簡単に検索を試したいので検索用のファイルをアップロードします。
[
{
"title": "reset.cssをNuxt.jsに導入する",
"body": "reset.cssをNuxt.jsのプロジェクトに導入する方法を書きます",
"tags": ["Nuxt.js", "reset.css"]
},
{
"title": "Nuxt.jsで必要なFont Awesomeだけをimportする",
"body": "Nuxt.jsでFont Awesomeを使用する際に使われる nuxt-fontawesome パッケージ。",
"tags": ["Nuxt.js"]
},
{
"title": "VueでのCSS Modulesの書き方",
"body": ""
},
{
"title": "Reset.cssをNext.jsに導入する",
"body": "Reset.cssをNext.jsに導入します、ここでは2つのやり方をご紹介します。",
"tags": ["Next.js", "reset.css"]
}
]
自分のブログの記事データをいくつか適当に、そこに対してタグを設定した状態で上げてみました。
なおここでのアップロードはJSON以外にも、CSV, TSVが対応しています。
3. 検索対象のリストを作成(重み付けも合わせて)
検索対象とする属性を設定します。
また、どの属性を優先的に検索対象とするかを設定します。
例えば↑の画像の場合、
body
を検索対象から外し、優先度はtags
の方がtitle
よりも高い、という設定になります。
Nuxt.jsへの実装
公式にVueを実装するやり方があるためそちらを参考にします
https://www.algolia.com/doc/guides/building-search-ui/getting-started/vue/
必要な値を取得する
必要な値は3つ。
- index名
- Application ID
- Search-Only API Key
index名は、Algolia作成時に付けたもの。
Application ID
とSearch-Only API Key
はAogoriaのAPI Keysページに載っています。
これらの値は実装時に使用します。
ライブラリのインストールとNuxtの設定
検索に必要なのはalgoliasearch
。
UIを簡単に実装するのにvue-instantsearch
とinstantsearch.css
の2つを使います。
$ yarn add vue-instantsearch algoliasearch instantsearch.css
pluginsの作成
Vue.use()
を使う必要があるためpluginsを使います。
私のプロジェクトではTypeScriptを使っているので.ts
で作成、またvue-instantsearch
がTypeScript未対応のため、ひとまず@ts-ignore
で回避。
import Vue from 'vue'
// @ts-ignore
import InstantSearch from 'vue-instantsearch'
Vue.use(InstantSearch)
作成したプラグインをnuxt.config.jsで設定。
mode: 'client'
を使用しないとエラーが起きてしまうので設定しています。
export default {
plugins: [{ src: '~/plugins/Algolia.ts', mode: 'client' }],
}
コンポーネントを作成
検索をするためのコンポーネントを作ります。
ここで先ほどの index名
・Application ID
・Search-Only API Key
を使用します。
<template>
<ais-instant-search :search-client="searchClient" index-name="<index名>">
<ais-search-box />
<ais-hits>
<div slot="item" slot-scope="{ item }">
<div>{{ item }}</div>
</div>
</ais-hits>
</ais-instant-search>
</template>
<script>
import algoliasearch from 'algoliasearch/lite'
import 'instantsearch.css/themes/algolia-min.css'
export default {
data() {
return {
searchClient: algoliasearch('<Application ID>', '<Search-Only API Key>'),
}
},
}
</script>
そして上記コンポーネントを使用するページでimportして呼び出します
<template>
<div>
<search />
・・・
</div>
</template>
<script>
import Search from '~/components/organisms/search/index.vue'
export default {
components: { Search }
・・・
}
</script>
検索が出来るようになりました!
ハイライト表示する
検索結果は以下のコードの部分です
<ais-hits>
<div slot="item" slot-scope="{ item }">
<div>{{ item }}</div>
</div>
</ais-hits>
item
は検索結果の1つになります。
↑は「nux」というワードで調べた時の結果。
_highlightResult.title.value
などに検索結果があるのが分かります。
そのため、先ほどのコードを以下のように書き換えてみると
<template>
<ais-instant-search :search-client="searchClient" index-name="TECH-BROCCOLI">
<ais-search-box />
<ais-hits>
<div slot="item" slot-scope="{ item }">
<div v-html="item._highlightResult.title.value" />
<div v-html="item._highlightResult.body.value" />
</div>
</ais-hits>
</ais-instant-search>
</template>
検索結果にハイライトしながら表示出来るようになりました!
課題
Nuxt.jsで実装時の課題としてCSR/SSRのDOMの違いに関するwarningメッセージがコンソールに表示されます。
プラグインでUI実装のためのvue-instantsearch
を使ったのが良くなかったかな… 🤔
今回はAlgoliaの検索が出来る事を簡単に確認したかったので、
vue-instantsearch
とinstantsearch.css
を使いましたが、
次はこれらを使わずに実装してみたいと思います!