Skip to content

Sort and price range

A sort dropdown and a min/max price filter with change-sort and change-price.

A collection toolbar with two controls: <change-sort> re-sorts the grid server-side and <change-price> filters by a min/max range. Both live inside <storesynk-collection> and update the grid, the URL, and the facet counts in one round trip.

<storesynk-collection handle="example-collection" page-size="12">
<div class="toolbar">
<!-- A native <select>; option values are "KEY" or "KEY:reverse". -->
<change-sort>
<select aria-label="Sort by">
<option value="">Featured</option>
<option value="PRICE">Price: low to high</option>
<option value="PRICE:reverse">Price: high to low</option>
<option value="TITLE">Alphabetical</option>
<option value="CREATED:reverse">Newest</option>
</select>
</change-sort>
<!-- Price range: [min-input]/[max-input]/[apply] mark native children.
The component doesn't name these inputs - add aria-label yourself (SSK-501). -->
<change-price class="price-range">
<input type="number" min-input placeholder="Min" aria-label="Minimum price" />
<input type="number" max-input placeholder="Max" aria-label="Maximum price" />
<button apply>Go</button>
</change-price>
</div>
<product-list class="grid">
<storesynk-product class="card">
<product-link>
<a>
<show-image main class="card-img"><img alt="" /></show-image>
<span class="card-title"><show-title></show-title></span>
</a>
</product-link>
<show-price class="card-price"></show-price>
</storesynk-product>
</product-list>
</storesynk-collection>
  • <change-sort> binds a native <select>. Option values are a Shopify sort key, optionally suffixed with :reverse. It reflects the active sort back into the dropdown, e.g. when restored from a shared URL.
  • <change-price> wires native children by marker attribute (min-input, max-input, apply) and applies an exclusive {price: {min, max}} filter.
  • <change-price> never names its inputs, and a placeholder is not a name. Give each an aria-label or a <label>; the validator enforces this as SSK-501.

Neither tag takes configuration attributes; you configure them through their children:

TagChild contract
change-sortA <select> whose <option> values are KEY or KEY:reverse (Shopify ProductCollectionSortKeys, e.g. PRICE, TITLE, CREATED; "" = default order).
change-priceAn input marked min-input, an input marked max-input, and an apply-marked element or <button>. Markers go on native elements, not Storesynk tags.

Set the initial sort with sort-key and reverse on <storesynk-collection> itself.

change-price { display: inline-flex; gap: 8px; align-items: center; }
change-price[ss-empty] { display: none; } /* no price facet on this collection */
  • A control that renders but does nothing is outside <storesynk-collection> (SSK-110). See collections troubleshooting.
  • In catalog mode (empty handle), only RELEVANCE and PRICE sort; other keys fall back to the default order.
  • [ss-empty] on <change-price> means the merchant hasn’t enabled the Price filter in the Search & Discovery app.