はじめに
Gatsbyブログに検索機能を付けたく、いくつかやりかたを調べてみた。
- Googleカスタム検索を使う
- Algoliaという有名な検索サービス(SaaS)を使う
- 自分用の検索と割り切りVSCodeの検索で頑張る
このうち、今回はGoogleカスタム検索を使って実装してみた。 本記事では実装した内容をメモする。
結果としては、以下の理由で不採用とした。
- 検索結果に記事がすべて出てこない。(Googleにインデックスされている記事しか出てこない)
- 広告が表示されることがある
検索を使うのは主に自分だろうということもあり、記事がすべて出てこないのは厳しい。 ただ、致命的はほどの欠点でもなく、今後使うこともあるかもしれないためやり方だけメモっておく。
最終的に採用したAlgoliaの導入は別途。
できあがりイメージ
インデックスされている記事は表示される。広告も出ないときは良い感じ。
インデックスされていない記事は表示されない。さらに、広告がたまに出る。
モチベーション
このブログは個人的に勉強したことのメモの側面があるため、自分の過去の記憶を頼りに記事を探したい。検索機能が必要となる。
はてなブログの時には良い感じに全文検索機能を提供してくれていた。
実現が難しいようであれば、最悪VSCodeの検索機能で諦めよう…と思いつつ実施。
実施内容
検索エンジンの作成
Googleカスタム検索画面から、新規の「検索エンジン」を作成する。
以下のように作成できればOK。
埋め込みコードの確認
埋め込みコードの確認画面から、以下のコードを取得できる。
<script async src="https://cse.google.com/cse.js?cx={検索エンジンID}">
</script>
<div class="gcse-search"></div>
これをブログ内に埋め込む。
Gatsbyブログへのコード設定
以下のサイトを参考に実施。
<Search>
コンポーネントを作成する。
import * as React from "react"
const Search = () => {
React.useEffect(() => {
if (typeof document !== "undefined") {
const cx = "{検索エンジンID}" //各自検索エンジンIDを入れる
let gcse = document.createElement("script")
gcse.type = "text/javascript"
gcse.async = true
gcse.src = "https://cse.google.com/cse.js?cx=" + cx
let s = document.getElementsByTagName("script")[0]
s.parentNode.insertBefore(gcse, s)
}
}, [])
return (
<div className="gcse-search"></div>
)
}
export default Search
以下のコードで、Googleから示されている<script></script>
タグを生成している。
const cx = "{検索エンジンID}" //各自検索エンジンIDを入れる
let gcse = document.createElement("script")
gcse.type = "text/javascript"
gcse.async = true
gcse.src = "https://cse.google.com/cse.js?cx=" + cx
let s = document.getElementsByTagName("script")[0]
s.parentNode.insertBefore(gcse, s)
これだけだと、
document is not defined
のエラーが出てしまうので、
if (typeof document !== "undefined") {
}
の処理を入れる。
この処理は以下のサイトを参考にしている。
なぜdocumentやwindowが定義されていないと怒られているのかというと、サーバーサイドでブラウザ用のグローバル変数を使おうとしているためです。
Next.jsはサーバーサイド、クライアントサイド両方で動くフレームワーク。そのため、定義したソースはサーバー、ブラウザ両方の環境で実行されます。
そして、documentやwindowはクライアントだけで定義されているグローバル変数です。サーバー環境で動かそうとすると「そんなグローバル変数は定義されていない!」とエラーが発生します。
さらに、この状態だと、コンポーネントが表示されたり消えたりを繰り返す事象が発生したので、useEffect
を入れる。
React.useEffect(() => {
}, [])
これで完了。
まとめ
- GatsbyブログにGoogleカスタム検索を導入した。
- 不採用とはしたが、今後使うときにはこのメモを参考にする。