テクニック

Shopify予測検索のカスタマイズ|検索候補の対象・件数・見た目を変える

この記事の対象: Shopify のテーマファイルを編集できる制作者
読了時間: 約12分

Shopify の予測検索(Predictive Search)は、検索フォームに文字を打った時点でリアルタイムに候補を表示する機能で、Dawn をはじめとする Online Store 2.0 テーマに標準搭載されている。ただ、デフォルトのままだと商品しか候補に出ない、サムネイルがない、件数が足りないなど、運用に合わない場面は多い。この記事では、予測検索の「対象リソース」「表示件数」「見た目」を実際にコードを編集して変える手順を、ファイルパスとコード付きで解説する。最後に、検索されているのに結果が出ない語をどう拾うかまで扱う。


前提:対象テーマと編集に必要な環境

前提:対象テーマと編集に必要な環境

この記事の手順は以下の環境を前提にしている。

  • テーマ: Online Store 2.0 対応テーマ(Dawn 15.0 以降で動作確認)
  • 編集方法: Shopify 管理画面 →「オンラインストア」→「テーマ」→「コードを編集」
  • 必要な権限: テーマファイルの編集権限(「テーマ」メニューが表示されない場合はストアオーナーに権限を確認する)
  • CLI を使う場合: Shopify CLI 3.x 以降 + shopify theme dev でローカルプレビュー可能

Dawn 以外の Online Store 2.0 テーマでもファイル構成が似ていれば応用できるが、ファイル名やクラス名はテーマによって異なる。自分のテーマの sections/ と assets/ を確認してから作業を始めること。

テーマ選びの段階から検索の使い勝手まで視野に入れたい場合は、こちらの記事も参考になる。


予測検索の対象リソースと件数を変える

予測検索の対象リソースと件数を変える

予測検索の仕組み

Dawn の予測検索は、次の流れで動いている。

予測検索の処理フロー
入力検索フォームに文字を打つ
リクエストJSがPredictive Search APIを呼ぶ
レンダリングAPIがLiquidセクションをHTMLで返す
表示返ってきたHTMLをドロップダウンに挿入

ポイントは「APIが Liquid セクションをレンダリングして返す」という点。つまり、候補の表示内容を変えるには JavaScript(API リクエスト側)と Liquid セクション(表示側)の両方を編集する必要がある。

API のエンドポイントは /search/suggest で、クエリパラメータで対象リソースと件数を指定する。

resources[type] で検索対象を増やす

デフォルトの Dawn では、予測検索が product のみを対象にしていることが多い。ブログ記事(article)・固定ページ(page)・コレクション(collection)も候補に出すには、API リクエストの resources[type] パラメータを変更する。

対象ファイル: assets/predictive-search.js

このファイル内で API リクエストの URL を組み立てている箇所を探す。fetch を呼び出している行の近くに resources[type] の記述があるはずだ。見つからなければ、ファイル内を resources で検索する。

該当箇所を次のように書き換える。

// assets/predictive-search.js 内の fetch URL 組み立て箇所を編集する
// 変更前: resources[type]=product のみ
// 変更後: 商品・記事・ページ・コレクションを対象に追加

const limit = this.getAttribute('data-results-limit') || '4';
const searchParams = new URLSearchParams({
  q: searchTerm,
  'resources[type]': 'product,article,page,collection',
  'resources[limit]': limit,
  'resources[limit_scope]': 'each',
  section_id: 'predictive-search',
});

const url = `${routes.predictive_search_url}?${searchParams.toString()}`;

各パラメータの意味は以下の通り。

パラメータ 値の例 説明
resources[type] product,article,page,collection 検索対象のリソース。カンマ区切りで複数指定
resources[limit] 1〜10 取得する件数
resources[limit_scope] each または all each: タイプごとに limit 件。all: 全タイプ合計で limit 件

limit_scope の違いは重要。all のままだと全タイプ合計で limit 件になるため、商品だけで枠が埋まって記事やページが一切出ない状態になりやすい。複数リソースを対象にするなら each に変更することを推奨する。


セクションを編集してサムネイル付きで記事・ページを表示する

セクションを編集してサムネイル付きで記事・ページを表示する

API の対象を増やしても、Liquid セクション側に表示コードがなければ画面には何も出ない。sections/predictive-search.liquid に、記事・ページ・コレクションの表示ブロックを追加する。

対象ファイル: sections/predictive-search.liquid

記事の検索結果を表示する

商品の表示ループ(predictive_search.resources.products を回しているブロック)の直後に、次のコードを追加する。

{%- if predictive_search.resources.articles.size > 0 -%}
  <div class="predictive-search__section">
    <h3 class="predictive-search__heading">ブログ記事</h3>
    <ul class="predictive-search__results-list" role="listbox">
      {%- for article in predictive_search.resources.articles -%}
        <li class="predictive-search__list-item" role="option">
          <a href="{{ article.url }}" class="predictive-search__item predictive-search__item--link">
            {%- if article.image -%}
              <img
                src="{{ article.image | image_url: width: 80 }}"
                alt="{{ article.image.alt | escape }}"
                width="80"
                height="80"
                loading="lazy"
                class="predictive-search__image"
              >
            {%- endif -%}
            <div class="predictive-search__item-content">
              <p class="predictive-search__item-heading">{{ article.title }}</p>
              <p class="predictive-search__item-description">
                {{ article.content | strip_html | truncatewords: 15 }}
              </p>
            </div>
          </a>
        </li>
      {%- endfor -%}
    </ul>
  </div>
{%- endif -%}

ページの検索結果を表示する

記事ブロックの直後に追加する。ページには image プロパティがないため、サムネイル部分は省いている。

{%- if predictive_search.resources.pages.size > 0 -%}
  <div class="predictive-search__section">
    <h3 class="predictive-search__heading">ページ</h3>
    <ul class="predictive-search__results-list" role="listbox">
      {%- for page in predictive_search.resources.pages -%}
        <li class="predictive-search__list-item" role="option">
          <a href="{{ page.url }}" class="predictive-search__item predictive-search__item--link">
            <div class="predictive-search__item-content">
              <p class="predictive-search__item-heading">{{ page.title }}</p>
              <p class="predictive-search__item-description">
                {{ page.content | strip_html | truncatewords: 15 }}
              </p>
            </div>
          </a>
        </li>
      {%- endfor -%}
    </ul>
  </div>
{%- endif -%}

コレクションの検索結果を表示する

{%- if predictive_search.resources.collections.size > 0 -%}
  <div class="predictive-search__section">
    <h3 class="predictive-search__heading">コレクション</h3>
    <ul class="predictive-search__results-list" role="listbox">
      {%- for collection in predictive_search.resources.collections -%}
        <li class="predictive-search__list-item" role="option">
          <a href="{{ collection.url }}" class="predictive-search__item predictive-search__item--link">
            {%- if collection.image -%}
              <img
                src="{{ collection.image | image_url: width: 80 }}"
                alt="{{ collection.image.alt | escape }}"
                width="80"
                height="80"
                loading="lazy"
                class="predictive-search__image"
              >
            {%- endif -%}
            <div class="predictive-search__item-content">
              <p class="predictive-search__item-heading">{{ collection.title }}</p>
            </div>
          </a>
        </li>
      {%- endfor -%}
    </ul>
  </div>
{%- endif -%}

読者が変更すべき箇所:

  • 各 <h3> の見出しテキスト(「ブログ記事」「ページ」「コレクション」)→ ストアの呼び方に合わせる
  • truncatewords: 15 の数字 → 説明文の長さを調整
  • サムネイルの width: 80 → 大きくしたければ 120 など。height も同じ値にする

サムネイルの CSS を追加する

上のコードで使っている predictive-search__image などのクラスに、スタイルを当てる。Dawn のデフォルト CSS にすでに定義がある場合は、そちらを上書きする形で調整する。

対象ファイル: assets/section-predictive-search.css(なければテーマの CSS ファイル)

.predictive-search__item--link {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 0.8rem 1.6rem;
  text-decoration: none;
  color: inherit;
}

.predictive-search__image {
  width: 5rem;
  height: 5rem;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
}

.predictive-search__item-content {
  flex: 1;
  min-width: 0;
}

.predictive-search__item-heading {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.predictive-search__item-description {
  margin: 0.2rem 0 0;
  font-size: 1.2rem;
  color: rgba(0, 0, 0, 0.6);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.predictive-search__section + .predictive-search__section {
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  padding-top: 0.8rem;
}

.predictive-search__heading {
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(0, 0, 0, 0.45);
  padding: 0.4rem 1.6rem;
  margin: 0;
}

Dawn はルートのフォントサイズが 10px に設定されていることが多く、1.4rem は 14px 相当になる。テーマの設定を確認して調整すること。

読者が変更すべき箇所:

  • width: 5rem / height: 5rem → サムネイルの大きさ
  • border-radius: 4px → 角丸の度合い(0 で四角)
  • color: rgba(0, 0, 0, 0.6) → 説明文の色。ダークテーマなら rgba(255, 255, 255, 0.6) のように白系にする
  • -webkit-line-clamp: 2 → 説明文の行数上限

Shopify のカスタマイズでどこまで対応できるかを俯瞰したいときは、こちらの記事が役立つ。


検索されているのに結果が出ない語を見つけて対処する

検索されているのに結果が出ない語を見つけて対処する

予測検索の見た目を整えても、ヒットしなければ意味がない。「ユーザーが検索しているのに0件になる語」を把握して、商品情報やコンテンツを見直す作業が欠かせない。

Shopify の検索分析で0件ヒットの語を洗い出す

Shopify 管理画面 →「ストア分析」→「検索」で、ストア内検索のデータを確認できる。注目すべきは次の2つ。

  • 結果がなかった検索クエリ: ユーザーが探しているのにヒットしなかった語
  • クリックされなかった検索クエリ: ヒットはしたが、求めていた情報と違った可能性がある語

これらの語に対する具体的な対処は以下の通り。

状況 対応
商品の別名・略称で検索されている 商品のタグに別名を追加する
カテゴリ名で検索されている 該当コレクションのタイトルや説明文に語を含める
FAQ 的な質問で検索されている ブログ記事やページを作成し、検索対象に含める
在庫切れ商品が検索されている 在庫切れ時の表示設定を見直す(テーマ設定で変更可能)
0件ヒット語への対応フロー
発見検索分析で0件の語を確認
分類商品名か・カテゴリかを判別
登録タグ・説明文・記事で語を補う

検索語を拾って商品情報を整えるサイクルを月1回でも回すと、検索経由の回遊率が改善しやすい。

検索まわりの改善と合わせて、SEO の観点で URL 構造の制約も把握しておくと手戻りが減る。

0件ヒット時にフォールバックを表示する

検索結果が何もないとき、空のドロップダウンが出るだけでは不親切だ。おすすめコレクションや全商品ページへのリンクを表示して、離脱を防ぐ。

対象ファイル: sections/predictive-search.liquid

結果表示ブロックの末尾(閉じタグの手前)に、次のコードを追加する。

{%- if predictive_search.resources.products.size == 0
  and predictive_search.resources.articles.size == 0
  and predictive_search.resources.pages.size == 0
  and predictive_search.resources.collections.size == 0 -%}
  <div class="predictive-search__no-results">
    <p>「{{ predictive_search.terms }}」に一致する結果が見つかりませんでした。</p>
    <p>
      <a href="{{ routes.collections_url }}/all">すべての商品を見る</a>
    </p>
  </div>
{%- endif -%}

読者が変更すべき箇所:

  • /all → 特定のコレクションに誘導したい場合は /collections/your-collection-handle に変更する
  • 「すべての商品を見る」→ ストアに合った誘導文に変更する

テーマ設定から件数を変更できるようにする

テーマ設定から件数を変更できるようにする

件数をコードに直書きしていると、変更するたびにテーマファイルを開くことになる。セクションスキーマに設定項目を追加すれば、テーマエディタの管理画面から変更できるようになる。

スキーマに件数設定を追加する

対象ファイル: sections/predictive-search.liquid

ファイル末尾の {% schema %} ブロックを編集する。settings 配列に range タイプの設定を追加する。

{
  "name": "Predictive search",
  "settings": [
    {
      "type": "range",
      "id": "results_per_type",
      "min": 2,
      "max": 10,
      "step": 1,
      "default": 4,
      "label": "リソースごとの表示件数"
    }
  ]
}

すでに settings 配列がある場合は、既存の項目の後ろにカンマを入れて追記する。配列ごと上書きすると既存の設定が消えるため注意。

JavaScript 側で設定値を受け取る

設定した値を JavaScript に渡すには、検索フォームが置かれている Liquid ファイルで data 属性を使う。

Dawn の場合、snippets/header-search.liquid や header.liquid 内の <predictive-search> タグが該当することが多い。テーマによってファイル名が違うため、テーマファイル内を predictive-search で検索して特定する。

<predictive-search
  data-results-limit="{{ settings.results_per_type | default: 4 }}"
>

assets/predictive-search.js 側では、先ほどのコードで this.getAttribute('data-results-limit') から値を取得する形にしてあるため、そのまま連動する。

ただし注意点がある。predictive-search.liquid のスキーマに追加した設定は、そのセクションの section.settings で参照するもので、テーマ全体の settings とは別。ヘッダーなど別のセクションから参照するには、settings_schema.json にテーマ全体設定として追加するか、JavaScript で直接値を渡す方法を使う必要がある。


うまくいかないとき

うまくいかないとき

予測検索のカスタマイズで起きやすいトラブルと対処法をまとめる。

候補が表示されない

  • JavaScript のエラーを確認する: ブラウザの開発者ツール → Console タブでエラーが出ていないか見る。URL の組み立てでスペルを間違えると 400 Bad Request が返る
  • resources[type] のスペルを確認する: 指定できるのは product、article、page、collection、query のみ。存在しないタイプ名を入れるとエラーになる
  • section_id がファイル名と一致しているか: section_id=predictive-search はファイル名が predictive-search.liquid である前提の値。ファイル名を変えた場合は ID も合わせる

記事やページが候補に出てこない

  • API レスポンスを直接確認する: ブラウザのアドレスバーに https://あなたのストア.myshopify.com/search/suggest.json?q=テスト&resources[type]=article&resources[limit]=4 を入力して、JSON に記事が含まれるか確認する
  • 記事が公開済みか: 下書き状態の記事は検索対象にならない
  • Liquid の変数名を確認する: predictive_search.resources.articles のスペルに注意。article(単数形)ではなく articles(複数形)

サムネイルが表示されない

  • 画像が設定されているか: 記事にアイキャッチ画像を設定していないと article.image は nil を返す。コード内の {%- if article.image -%} で分岐しているため、画像なしの記事では何も表示されない
  • image_url フィルタの書式: | image_url: width: 80 は Shopify 独自の Liquid フィルタ。標準 Liquid には存在しないため、他のテンプレートエンジンからの移植時にエラーが出やすい

テーマのアップデートで変更が消える

テーマファイルを直接編集しているため、テーマ更新時に上書きされる可能性がある。テーマを複製してから作業する、変更箇所にコメントで印を残す、Shopify CLI + Git で差分管理するといった対策が有効。詳しくは「よくある質問」の該当項目を参照。


よくある質問

よくある質問

Shopifyの予測検索で記事やページも候補に出せますか?

Predictive Search API の resources[type] パラメータに article や page を追加すれば、検索候補に含められる。ただし、API 側の設定だけでは画面に表示されない。セクションの Liquid ファイルにも表示用コードを追加する必要がある。

予測検索の表示件数は最大何件まで設定できますか?

resources[limit] の上限は 10。resources[limit_scope] を each にすれば、リソースタイプごとに最大10件ずつ取得できる。ただし候補が多すぎるとドロップダウンが長くなり操作性が落ちるため、4〜6件が実用的な範囲。

Dawn以外のテーマでも同じ方法でカスタマイズできますか?

Online Store 2.0 対応テーマであれば Predictive Search API は共通で使える。ファイル名やクラス名がテーマによって異なるため、テーマ内を predictive-search でファイル検索して該当ファイルを特定してから作業する。Online Store 1.0(Vintage テーマ)では予測検索の仕組み自体が異なるため、この記事の手順はそのまま適用できない。

カスタマイズがテーマ更新で上書きされることはありますか?

テーマファイルを直接編集しているため、テーマのアップデートで上書きされる可能性はある。対策として、更新前にテーマを複製しておくこと、変更箇所に /* CUSTOM: predictive search */ や {% comment %}CUSTOM{% endcomment %} のようなコメントで印を残しておくことが有効。Shopify CLI で Git 管理していれば、差分の確認と復元が確実にできる。

予測検索のカスタマイズと通常の検索結果ページは別の設定ですか?

別の設定になる。予測検索は /search/suggest エンドポイントと sections/predictive-search.liquid が担当し、通常の検索結果ページは /search と templates/search.liquid(または templates/search.json)が担当する。両方の表示を揃えたい場合は、それぞれ個別に編集する必要がある。


まとめ

Shopify の予測検索カスタマイズは、3つのファイルに対する作業に集約される。

  1. assets/predictive-search.js — API リクエストの resources[type] と resources[limit] を変更し、対象リソースと件数を調整する
  2. sections/predictive-search.liquid — 記事・ページ・コレクションの表示ブロックをサムネイル付きで追加する
  3. assets/section-predictive-search.css — サムネイルやレイアウトのスタイルを整える

加えて、Shopify 管理画面の検索分析で「0件ヒットの検索語」を月1回でも確認し、商品タグや記事コンテンツを見直すことで、検索の実効性が上がる。

Shopify でのストア構築の全体感を掴みたいときは、こちらの記事もあわせてどうぞ。