GatsbyブログにGoogleカスタム検索機能を導入したが微妙だった

2022/4/24

(最終更新: 2022/4/24

はじめに

Gatsbyブログに検索機能を付けたく、いくつかやりかたを調べてみた。

  • Googleカスタム検索を使う
  • Algoliaという有名な検索サービス(SaaS)を使う
  • 自分用の検索と割り切りVSCodeの検索で頑張る

このうち、今回はGoogleカスタム検索を使って実装してみた。 本記事では実装した内容をメモする。

結果としては、以下の理由で不採用とした。

  • 検索結果に記事がすべて出てこない。(Googleにインデックスされている記事しか出てこない)
  • 広告が表示されることがある

検索を使うのは主に自分だろうということもあり、記事がすべて出てこないのは厳しい。 ただ、致命的はほどの欠点でもなく、今後使うこともあるかもしれないためやり方だけメモっておく。

最終的に採用したAlgoliaの導入は別途。

できあがりイメージ

インデックスされている記事は表示される。広告も出ないときは良い感じ。

インデックスされている記事(Googleカスタム検索結果)

インデックスされていない記事は表示されない。さらに、広告がたまに出る。

広告が表示される場合

モチベーション

このブログは個人的に勉強したことのメモの側面があるため、自分の過去の記憶を頼りに記事を探したい。検索機能が必要となる。

はてなブログの時には良い感じに全文検索機能を提供してくれていた。

はてなブログのときの検索機能

実現が難しいようであれば、最悪VSCodeの検索機能で諦めよう…と思いつつ実施。

実施内容

検索エンジンの作成

Googleカスタム検索画面から、新規の「検索エンジン」を作成する。

以下のように作成できればOK。

検索エンジン設定

埋め込みコードの確認

埋め込みコードの確認画面から、以下のコードを取得できる。

<script async src="https://cse.google.com/cse.js?cx={検索エンジンID}">
</script>
<div class="gcse-search"></div>

これをブログ内に埋め込む。

Gatsbyブログへのコード設定

以下のサイトを参考に実施。

参考資料

Gatsby.jsにGoogleカスタム検索エンジンを設置する方法 | 謎の技術研究部

<Search>コンポーネントを作成する。

src/components/organisms/search.js
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はクライアントだけで定義されているグローバル変数です。サーバー環境で動かそうとすると「そんなグローバル変数は定義されていない!」とエラーが発生します。

Next.jsで「document is not defined」と怒られたときの対処法 - Qiita

さらに、この状態だと、コンポーネントが表示されたり消えたりを繰り返す事象が発生したので、useEffectを入れる。

React.useEffect(() => {

}, [])

これで完了。

まとめ

  • GatsbyブログにGoogleカスタム検索を導入した。
  • 不採用とはしたが、今後使うときにはこのメモを参考にする。


個別連絡はこちらへ→Twitterお問い合わせ

プロフィール

プロフィールイメージ

はち子

事業会社のシステム部門で働きはじめて5年目の会社員。システム企画/要件定義/システムアーキテクチャ等。

Twitter→@bun_sugi

過去の記事について

はてなブログに掲載の記事(主にプログラミングメモ)についてはこちらに掲載しております。(本ブログに移行中)

タグ一覧

関連記事

Copyright© 2023, エンジニアを目指す日常ブログ

お問い合わせ|プライバシーポリシー