# Predictive search

> A search field that shows products and search suggestions as the visitor types, in a popover or right on the page. Covers smootify-search, its regions, the result template and the link to the search page.

Status: Ready (Smootify 2.0)  
Add-on: Predictive Search  
URL: https://www.smootify.io/docs/astro/build/predictive-search  
Updated: 2026-10-21

Predictive search shows results while the visitor types: up to 10 products, and the searches Shopify suggests for those words. It usually sits in the navbar, with the results in a popover. For the full list of results, pair it with a [search results page](https://www.smootify.io/docs/astro/build/search-page).

> [!NOTE]
> Turn on the **Predictive Search** add-on in the Smootify dashboard. The Lite and Server plans include it. On localhost and on your `*.workers.dev` address it works without it, so you can build and test first. Shopify's Search & Discovery app can tune the results, for example with synonyms, but it is not required.

## How it fits together

What Smootify needs:

- a `smootify-search` element;
- inside it, a text `<input name="query">`, in a `<form>`.

What is up to you:

- where the results appear: in a popover, or in place on the page, such as in a menu panel;
- which parts you use: the result list, the suggestions, the empty message, the content shown before the visitor types;
- how a result looks: a simple result template, or a full product card.

```html
<smootify-search>
  <form><input type="search" name="query"></form>
  <div popover="auto">
    <search-with-query>
      <search-result>
        <a search="url" href="#"><img search="image" alt="" width="48" height="48"><div search="title">Product name</div><div search="price">$0.00</div></a>
      </search-result>
      <search-empty><div>No products found</div></search-empty>
    </search-with-query>
  </div>
</smootify-search>
```

## 1. Add the search field

1. Add a [`smootify-search`](https://www.smootify.io/docs/astro/reference/elements/smootify-search) element.
2. Inside it, add a `<form>` with one text `<input>`. Smootify searches with it whatever its `name`. With two text inputs, set the `name` of the search one to `query`.

Smootify searches a short moment after the visitor stops typing, and when they press Enter. The submit button is optional.

`limit` on `smootify-search` sets how many products show, up to 10, which is also the default. Shopify returns at most 10 products for a predictive search.

## 2. Choose where the results appear

The results can appear in one of two places:

| Where | Put the results | Opens and closes |
|---|---|---|
| A popover | inside a `[popover]` (see [Popovers](https://www.smootify.io/docs/astro/build/popovers)) | opens when the visitor clicks the field, so the suggestions for an empty field show, and as they type; a `button` with `data-action="close"` anywhere in `smootify-search`, such as next to the field, closes it |
| In place | anywhere in `smootify-search`, with no popover | each part shows and hides itself where it is, such as in a full-screen menu |

## 3. The regions

These elements show and hide themselves with the state of the search. All are optional:

| Tag | Shown while | Holds, for example |
|---|---|---|
| `search-no-query` | the field is empty | your own suggestions, such as popular searches |
| `search-with-query` | the field has words in it | the results, the empty message, Shopify's suggestions |
| `search-empty` | the words found no product | a message such as "No products found" |
| `search-suggestions` | Shopify has search suggestions for the words | Shopify's suggestions; put it inside `search-with-query` |

## 4. The results

There are two ways to show a result:

- **A result template**, `search-result`: an element with `search="…"` values inside, copied once per product. Prices with `search="price"` and `search="compare-at-price"`: a `smootify-price` inside it has no product to read.
- **A product card**, `smootify-product` with `data-id="search"` inside `search-with-query`, designed as a product card: it shows everything a product card shows, such as `smootify-price` or an add-to-cart button, but each card loads the whole product from Shopify.

**A result template.** Add a [`search-result`](https://www.smootify.io/docs/astro/reference/elements/search-result) element. It is the template: Smootify copies it once per product, and removes other `search-result` elements you wrote. Inside it, `search="…"` fills an element with a value of the product:

- `search="title"`, `search="vendor"`, `search="type"`: text;
- `search="url"` on an `<a>`: the product page’s link;
- `search="image"` on an `<img>`: the product’s main image;
- `search="price"`: the lowest price of the product;
- `search="compare-at-price"`: its crossed-out price, removed when it is not on sale;
- `search="collection"`: the first collection’s name, with its link on an `<a>`.

`image`, `compare-at-price` and `collection` are removed when the product has none. A result that cannot be bought gets the class `is-not-available`. Every value is in [predictive search attributes](https://www.smootify.io/docs/astro/reference/attributes/predictive-search).

**A product card.** Instead of `search-result`, put a `smootify-product` with `data-id="search"` inside `search-with-query`, and design it as a [product card](https://www.smootify.io/docs/astro/build/product-cards). The first card is the template.

```html
<search-with-query>
  <div class="sm-dyn-item">
    <smootify-product data-id="search">
      <a product="url" href="#">Product name</a>
      <smootify-price><div data-prop="price">$0.00</div></smootify-price>
    </smootify-product>
  </div>
</search-with-query>
```

## 5. Suggestions, the typed words and the search page

```html
<search-no-query>
  <div>Popular searches</div>
  <a href="/search/" search="suggested-query">Sneakers</a>
</search-no-query>
<search-with-query>
  <div>Results for <span search="query">shoes</span></div>
  <search-suggestions><a href="/search/" search="suggested-query">Suggestion</a></search-suggestions>
  <a href="/search/" search="search-page">See all results</a>
</search-with-query>
```

- **Shopify’s suggestions.** Inside `search-suggestions`, an `<a>` with `search="suggested-query"` is the template of one suggestion. A click searches it. Put `search-suggestions` inside `search-with-query`: suggestions only exist once the visitor has typed.
- **Your own suggestions.** In `search-no-query`, links with `search="suggested-query"` are fixed suggestions, such as popular searches. A click searches their text. Keep them outside `search-suggestions`.
- **The typed words.** `search="query"` on text shows what the visitor typed, for example in “Results for shoes”.
- **The search page.** A link with `search="search-page"` and an `href` that is your search page, such as `/search/`, gets the typed words added to its address, so the search page opens with the same search. Enter in the field opens it too.

## While it loads

While a search runs, `smootify-search` has the class `is-loading`. Nothing shimmers by default: style that class, or add `skeleton` to the elements in the result template. Smootify also sets `has-query`, `has-products`, `is-empty` and `has-suggestions` on `smootify-search`. See [state classes](https://www.smootify.io/docs/astro/reference/state-classes).

## Before you publish

> [!STUCK]
> - **Nothing happens when typing.** `smootify-search` has two text inputs, and neither has `name="query"`.
> - **Never more than 10 results.** That is Shopify's limit for predictive search. Add a link with `search="search-page"` to show all results.
> - **Prices are empty in the results.** A `smootify-price` inside `search-result` has no product to read. Use `search="price"`, or product cards.
> - **Attributes on the second result do nothing.** Only the first `search-result` is the template.
> - **Suggestions never show.** `search-suggestions` is inside `search-no-query`, which hides as soon as the visitor types. Move it into `search-with-query`.
> - **It works on localhost but not on the live domain.** The Predictive Search add-on is not turned on for the site.
