You can use the [Storefront API](/docs/api/storefront) 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.
## Requirements
- You've completed the [Getting started with the Storefront API](/docs/storefronts/headless/building-with-the-storefront-api/getting-started) guide.
- You're familiar with [querying products and collections](/docs/storefronts/headless/building-with-the-storefront-api/products-collections/getting-started).
- You've created [products](/docs/api/admin-graphql/latest/objects/product) and [collections](/docs/api/admin-graphql/latest/objects/collection) in your store.
- You've verified that an Online Store 2.0 compatible theme, such as [Dawn](/docs/storefronts/themes/tools/dawn), is installed by [checking if your theme supports filtering](https://help.shopify.com/en/manual/online-store/themes/customizing-themes/storefront-filters#check-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](https://help.shopify.com/en/manual/online-store/search-and-discovery). 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.
- Your Headless channel or custom app has the `unauthenticated_read_product_listings` [access scopes](/docs/api/usage/access-scopes). Learn how to [request permissions for Headless channels](/docs/storefronts/headless/building-with-the-storefront-api/manage-headless-channels#request-storefront-permissions).
- You're using API version 2022-01 or higher.
## Step 1: Query products
You can use the Storefront API to make the following queries:
- [Query products by collection](#query-products-by-collection)
- [Query products by type](#query-products-by-type)
- [Query products by vendor](#query-products-by-vendor)
- [Query products by variant options](#query-products-by-variant-options)
- [Query products by price](#query-products-by-price)
- [Query products in stock](#query-products-in-stock)
- [Query products by metafield value](#query-products-by-metafield-value)
### Query 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.
### Query 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.
### Query 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.
### Query 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`.
### Query 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.
#### Limitations
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:
### Query 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](/docs/api/storefront/2022-01/objects/queryroot).
### Query 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`](/docs/api/storefront/latest/input-objects/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.
#### Limitations
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.
## Step 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
## Step 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.
## Next steps
- Learn how to [create and update a cart](/docs/storefronts/headless/building-with-the-storefront-api/cart/manage) in Shopify with the Storefront API.
- Learn how to [manage customer accounts](/docs/storefronts/headless/building-with-the-customer-account-api/customer-accounts) with the Storefront API.
- Support [multiple languages](/docs/storefronts/headless/building-with-the-storefront-api/markets/multiple-languages) on a storefront with the Storefront API.
- Learn about the [different tools](/docs/storefronts/headless/additional-sdks) that you can use to create unique buying experiences anywhere your customers are, including websites, apps, and video games.