Skip to main content

Filter products in a collection with the Storefront API

You can use the Storefront API to filter products in a collection. This functionality lets you build a desired customer experience on a storefront, such as the ability to narrow down the search results that you display to customers.

This guide shows you how to filter products in a collection based product type, vendor, variant options, price, and whether the product is in stock.


  • You've created products and collections in your store.
  • You've verified that an Online Store 2.0 compatible theme is installed by checking if your theme supports filtering. The Online Store 2.0 theme does not need to be the published theme to enable product filtering.
  • You've installed the Shopify Search & Discovery app. By default, the app enables filters for the availability and price filters. To enable other built-in filters such as tags, vendor, or product type, click Search & Discovery > Filters > Edit filters.
  • You're using API version 2022-01 or higher.

Anchor to Step 1: Query productsStep 1: Query products

You can use the Storefront API to make the following queries:

Anchor to Query products by collectionQuery products by collection

To retrieve products by the collection that they belong to, you can query the collection's handle. You'll use the handle in subsequent steps in this tutorial to filter products in a collection based on product type, vendor, variant options, price, and whether the product is in stock.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query AllProducts {
collection(handle: "filterable-collection") {
handle
products(first: 10) {
edges {
node {
handle
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [{
"node": {
"handle": "product-a",
}
}]
}
}
}
}

Anchor to Query products by typeQuery products by type

You can query products in a collection by their type (productType). In the following example, products in the collection that have the "shoes" product type are returned. Make sure to enable Product Type filter in Search & Discovery > Filters > Edit filters.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query ProductType {
collection(handle: "filterable-collection") {
handle
products(first: 10, filters: { productType: "shoes"}) {
edges {
node {
handle
productType
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [{
"node": {
"handle": "product-a",
"productType": "shoes"
}
}]
}
}
}
}

Anchor to Query products by vendorQuery products by vendor

You can query products in a collection by vendor (productVendor). In the following example, products in the collection that are from a vendor called "bestshop" are returned. Make sure to enable Vendor filter in Search & Discovery > Filters > Edit filters.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query ProductVendor {
collection(handle: "filterable-collection") {
handle
products(first: 10, filters: { productVendor: "bestshop"}) {
edges {
node {
handle
vendor
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [{
"node": {
"handle": "product-a",
"productVendor": "bestshop"
}
}]
}
}
}
}

Anchor to Query products by variant optionsQuery products by variant options

Merchants can add variants to a product that has more than one option, such as size or color. Each combination of option values for a product can be a variant of that product.

You can query products by their variant option name (variantOptionName) and value (variantOptionValue). For example, a variant option's name might be color, and the variant option's value might be red.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query VariantOptions {
collection(handle: "filterable-collection") {
handle
products(
first: 10
filters: { variantOption: { name: "color", value: "red" } }
) {
edges {
node {
handle
variants(first: 10) {
edges {
node {
selectedOptions {
name
value
}
}
}
}
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [
{
"node": {
"handle": "product-a",
"variants": {
"edges": [
{
"node": {
"selectedOptions": [
{
"name": "color",
"value": "red"
}
]
}
}
]
}
}
}
]
}
}
}
}

Anchor to Query products by priceQuery products by price

You can query products in a collection by their price. In the following example, the first 10 products that are between the price range of 25.00 CAD and 50.00 CAD are returned.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query Price {
collection(handle: "filterable-collection") {
handle
products(
first: 10
filters: { price: { min: 25.0, max: 50.0 } }
) {
edges {
node {
handle
priceRange {
minVariantPrice {
amount
currencyCode
}
maxVariantPrice {
amount
currencyCode
}
}
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [
{
"node": {
"handle": "product-a",
"priceRange": {
"minVariantPrice": {
"amount": "29.99",
"currencyCode": "CAD"
},
"maxVariantPrice": {
"amount": "44.99",
"currencyCode": "CAD"
}
}
}
}
]
}
}
}
}

For filters of type price, passing in multiple ranges isn't supported. If you specify multiple price filters, then everything is ignored except for the first range. For example, the following filters are equivalent:

GraphQL input

{
filters: [
{ price: { min: 10 } },
{ price: { min: 5, max: 15 } }
]
}

GraphQL input

{
filters: [
{ price: { min: 10 } }
]
}

Anchor to Query products in stockQuery products in stock

To retrieve information about whether products and their associated variants are available for sale, you can specify the available: true filter and query the availableForSale field on the products object.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query InStock {
collection(handle: "filterable-collection") {
handle
products(first: 10, filters: { available: true}) {
edges {
node {
handle
availableForSale
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [
{
"node": {
"handle": "product-a",
"availableForSale": true,
}
}
]
}
}
}
}

Anchor to Query products by categoryQuery products by category

You can query products in a collection by standard category (category). In the following example, products in the collection that are from a category based on the id "aa-1-10-2" are returned. Make sure to enable Category filter in Search & Discovery > Filters > Edit filters.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query ProductCategory {
collection(handle: "filterable-collection") {
handle
products(
first: 10,
filters: { category: { id: "aa-1-10-2" } }
) {
edges {
node {
handle
category {
id
name
}
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [{
"node": {
"handle": "product-a",
"category": {
"id": "aa-1-10-2",
"name": "Coats & Jackets"
}
}
}]
}
}
}
}

Anchor to Query products by metafield valueQuery products by metafield value

You can query products in a collection by a product or variant metafield. Use either productMetafield or variantMetafield to specify the MetafieldFilter parameters.

The following example returns the first product that has a product metafield value of tumble dry for a metafield with a key of drying_instructions and a product_care namespace.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query tumbleDryProducts {
collection(handle: "filterable-collection") {
handle
products(first: 1,
filters: {
productMetafield:{
namespace:"product_care",
key:"drying_instructions",
value:"tumble dry"
}
}) {
edges {
node {
id
title
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [
{
"node": {
"id": "gid://shopify/Product/1",
"title": "First Product",
}
}
]
}
}
}
}

Product and variant metafield filters are available for metafields defined using the metafield types single_line_text_field, boolean, numeric_integer, numeric_decimal using API version 2022-04 or higher.


Anchor to Step 2: Combine filtersStep 2: Combine filters

You can combine filters in your queries to retrieve products in a collection that have a set of characteristics.

Different filters get combined using the AND operator. For example [{ productType: "shoes" }, { productVendor: "bestshop" }] returns products that have the productType "shoes" AND are from the productVendor "bestshop".

Multiples of the same filter get combined using the OR operator. For example, [{ productType: "shoes" }, { productType: "socks" }] returns products that have the productType socks OR shoes.

The following example shows how to query for products that have all the following characteristics:

  • Type: shoes
  • Vendor: bestshop
  • Color: blue

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query MultipleVariantOptionsWithInStock {
collection(handle: "filterable-collection") {
handle
products(first: 10, filters: [
{
productType: "shoes"
},
{
productVendor: "bestshop"
},
{
variantOption: {
name: "color",
value: "blue"
}
}
]) {
edges {
node {
handle
availableForSale
productType
vendor
variants(first: 10) {
edges {
node {
selectedOptions {
name
value
}
}
}
}
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"edges": [
{
"node": {
"handle": "product-a",
"availableForSale": true,
"productType": "shoes",
"productVendor": "bestshop",
"variants": {
"edges": [
{
"node": {
"selectedOptions": [
{
"name": "color",
"value": "blue"
}
]
}
}
]
}
}
},
{
"node": {
"handle": "product-b",
"availableForSale": true,
"productType": "shoes",
"productVendor": "bestshop",
"variants": {
"edges": [
{
"node": {
"selectedOptions": [
{
"name": "color",
"value": "red"
},
{
"name": "color",
"value": "blue"
}
]
}
}
]
}
}
}
]
}
}
}
}

Anchor to Step 3: Query available filtersStep 3: Query available filters

The following example shows how to query the available filters for products in a collection. You can use the response to construct a filter panel on a storefront.

The type field specifies two types of user interface (UI) components: LIST and PRICE_RANGE. LIST represents multiple choice options and PRICE_RANGE represents a range of prices.

Each filter includes a list of selectable values with a corresponding count that indicates how many products in the collection match the filter value. Each value has an input field with a JSON serialized value. The JSON serialized value matches the ProductFilter input schema and can be used as input to the filters field of the parent products field.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query Facets {
collection(handle: "filterable-collection") {
handle
products(first: 10) {
filters {
id
label
type
values {
id
label
count
input
}
}
}
}
}

JSON response

{
"data": {
"collection": {
"handle": "filterable-collection",
"products": {
"filters": [
{
"id": "filter.v.availability",
"label": "Availability",
"type": "LIST",
"values": [
{
"id": "filter.v.availability0",
"label": "Out of Stock",
"count": 3,
"input": "{\"available\":false}"
},
{
"id": "filter.v.availability1",
"label": "In Stock",
"count": 1,
"input": "{\"available\":true}"
}
]
},
{
"id": "filter.p.type",
"label": "Type",
"type": "LIST",
"values": [
{
"id": "filter.p.typeshoes",
"label": "Shoes",
"count": 3,
"input": "{\"productType\":\"shoes\"}"
},
{
"id": "filter.p.typesocks",
"label": "Socks",
"count": 1,
"input": "{\"productType\":\"socks\"}"
}
]
},
{
"id": "filter.p.vendor",
"label": "Vendor",
"type": "LIST",
"values": [
{
"id": "filter.p.vendorshoe-company",
"label": "Shoe Company",
"count": 3,
"input": "{\"productVendor\":\"shoe-company\"}"
},
{
"id": "filter.p.vendordsock-company",
"label": "Sock Company",
"count": 1,
"input": "{\"productVendor\":\"sock-company\"}"
}
]
},
{
"id": "filter.v.option.color",
"label": "Color",
"type": "LIST",
"values": [
{
"id": "filter.v.option.colorblue",
"label": "Blue",
"count": 1,
"input": "{\"variantOption\":{\"name\":\"color\",\"value\":\"blue\"}}"
},
{
"id": "filter.v.option.colorred",
"label": "Red",
"count": 1,
"input": "{\"variantOption\":{\"name\":\"color\",\"value\":\"red\"}}"
}
]
},
{
"id": "filter.v.option.size",
"label": "Size",
"type": "LIST",
"values": [
{
"id": "filter.v.option.titlesmall",
"label": "Small",
"count": 1,
"input": "{\"variantOption\":{\"name\":\"size\",\"value\":\"small\"}}"
},
{
"id": "filter.v.option.titlelarge",
"label": "Large",
"count": 1,
"input": "{\"variantOption\":{\"name\":\"size\",\"value\":\"large\"}}"
}
]
}
]
}
}
}
}


Was this page helpful?