---
title: products - Storefront API
description: >
  Returns a paginated list of the shop's
  [products](/docs/api/storefront/2026-04/objects/Product).


  For full-text storefront search, use the
  [`search`](/docs/api/storefront/2026-04/queries/search) query instead.
api_version: 2026-04
api_name: storefront
type: query
api_type: graphql
source_url:
  html: 'https://shopify.dev/docs/api/storefront/latest/queries/products'
  md: 'https://shopify.dev/docs/api/storefront/latest/queries/products.md'
---

# products

query

Returns a paginated list of the shop's [products](https://shopify.dev/docs/api/storefront/2026-04/objects/Product).

For full-text storefront search, use the [`search`](https://shopify.dev/docs/api/storefront/2026-04/queries/search) query instead.

## ProductConnection arguments

[ProductConnection!](https://shopify.dev/docs/api/storefront/latest/connections/ProductConnection)

* after

  [String](https://shopify.dev/docs/api/storefront/latest/scalars/String)

  Returns the elements that come after the specified cursor.

* before

  [String](https://shopify.dev/docs/api/storefront/latest/scalars/String)

  Returns the elements that come before the specified cursor.

* first

  [Int](https://shopify.dev/docs/api/storefront/latest/scalars/Int)

  Returns up to the first `n` elements from the list.

* last

  [Int](https://shopify.dev/docs/api/storefront/latest/scalars/Int)

  Returns up to the last `n` elements from the list.

* query

  [String](https://shopify.dev/docs/api/storefront/latest/scalars/String)

  You can apply one or multiple filters to a query. Learn more about [Shopify API search syntax](https://shopify.dev/api/usage/search-syntax).

  * available\_for\_sale

    Filter by products that have at least one product variant available for sale.

  * * created\_at

    * product\_type

    * tag

    * tag\_not

    * title

    * updated\_at

    * variants.price

    - Filter by the date and time when the product was created.

    - Example:

      * `created_at:>'2020-10-21T23:39:20Z'`
      * `created_at:<now`
      * `created_at:<=2024`

      Filter by a comma-separated list of [product types](https://help.shopify.com/en/manual/products/details/product-type).

    - Example:

      * `product_type:snowboard`

      Filter products by the product [`tags`](https://shopify.dev/docs/api/storefront/latest/objects/Product#field-tags) field.

    - Example:

      * `tag:my_tag`

      Filter by products that don't have the specified product [tags](https://shopify.dev/docs/api/storefront/latest/objects/Product#field-tags).

    - Example:

      * `tag_not:my_tag`

      Filter by the product [`title`](https://shopify.dev/docs/api/storefront/latest/objects/Product#field-title) field.

    - Example:

      * `title:The Minimal Snowboard`

      Filter by the date and time when the product was last updated.

    - Example:

      * `updated_at:>'2020-10-21T23:39:20Z'`
      * `updated_at:<now`
      * `updated_at:<=2024`

      Filter by the price of the product's variants.

  * vendor

    Filter by the product [`vendor`](https://shopify.dev/docs/api/storefront/latest/objects/Product#field-vendor) field.

    Example:

    * `vendor:Snowdevil`
    * `vendor:Snowdevil OR vendor:Icedevil`

* reverse

  [Boolean](https://shopify.dev/docs/api/storefront/latest/scalars/Boolean)

  Default:false

  Reverse the order of the underlying list.

* sort​Key

  [Product​Sort​Keys](https://shopify.dev/docs/api/storefront/latest/enums/ProductSortKeys)

  Default:ID

  Sort the underlying list by the given key.

***

## Possible returns

* edges

  [\[Product​Edge!\]!](https://shopify.dev/docs/api/storefront/latest/objects/ProductEdge)

  non-null

  A list of edges.

* filters

  [\[Filter!\]!](https://shopify.dev/docs/api/storefront/latest/objects/Filter)

  non-null

  A list of available filters.

* nodes

  [\[Product!\]!](https://shopify.dev/docs/api/storefront/latest/objects/Product)

  non-null

  A list of the nodes contained in ProductEdge.

* page​Info

  [Page​Info!](https://shopify.dev/docs/api/storefront/latest/objects/PageInfo)

  non-null

  Information to aid in pagination.

***

## Examples

* ### Retrieve first three products

  #### Description

  The following example shows how to query for first three products.

  #### Query

  ```graphql
  query getProducts($first: Int) {
    products(first: $first) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($first: Int) { products(first: $first) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($first: Int) {
      products(first: $first) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($first: Int) {
      products(first: $first) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjo2NTcyMTE2NSwibGFzdF92YWx1ZSI6IjY1NzIxMTY1In0=",
          "node": {
            "title": "Storefront Spoon"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoyNjMwNzE4NTYsImxhc3RfdmFsdWUiOiIyNjMwNzE4NTYifQ==",
          "node": {
            "title": "Storefront Shoes"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjo1Mzg4MjUyNjEsImxhc3RfdmFsdWUiOiI1Mzg4MjUyNjEifQ==",
          "node": {
            "title": "Guitar"
          }
        }
      ]
    }
  }
  ```

* ### Retrieve first three products in reverse order

  #### Description

  The following example shows how to query for first three products in reverse order.

  #### Query

  ```graphql
  query getProducts($first: Int, $reverse: Boolean) {
    products(first: $first, reverse: $reverse) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($first: Int, $reverse: Boolean) { products(first: $first, reverse: $reverse) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($first: Int, $reverse: Boolean) {
      products(first: $first, reverse: $reverse) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($first: Int, $reverse: Boolean) {
      products(first: $first, reverse: $reverse) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjo5Mjk4OTg0NjUsImxhc3RfdmFsdWUiOiI5Mjk4OTg0NjUifQ==",
          "node": {
            "title": "Camper Van"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjo1Mzg4MjUyNjEsImxhc3RfdmFsdWUiOiI1Mzg4MjUyNjEifQ==",
          "node": {
            "title": "Guitar"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoyNjMwNzE4NTYsImxhc3RfdmFsdWUiOiIyNjMwNzE4NTYifQ==",
          "node": {
            "title": "Storefront Shoes"
          }
        }
      ]
    }
  }
  ```

* ### Retrieve first two products after cursor

  #### Description

  The following example shows how to query for first two products after cursor.

  #### Query

  ```graphql
  query getProducts($first: Int, $after: String) {
    products(first: $first, after: $after) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($first: Int, $after: String) { products(first: $first, after: $after) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($first: Int, $after: String) {
      products(first: $first, after: $after) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($first: Int, $after: String) {
      products(first: $first, after: $after) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjoyNjMwNzE4NTYsImxhc3RfdmFsdWUiOiIyNjMwNzE4NTYifQ==",
          "node": {
            "title": "Storefront Shoes"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjo1Mzg4MjUyNjEsImxhc3RfdmFsdWUiOiI1Mzg4MjUyNjEifQ==",
          "node": {
            "title": "Guitar"
          }
        }
      ]
    }
  }
  ```

* ### Retrieve last two products before cursor

  #### Description

  The following example shows how to query for last two products before cursor.

  #### Query

  ```graphql
  query getProducts($last: Int, $before: String) {
    products(last: $last, before: $before) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($last: Int, $before: String) { products(last: $last, before: $before) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($last: Int, $before: String) {
      products(last: $last, before: $before) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($last: Int, $before: String) {
      products(last: $last, before: $before) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjo2NTcyMTE2NSwibGFzdF92YWx1ZSI6IjY1NzIxMTY1In0=",
          "node": {
            "title": "Storefront Spoon"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoyNjMwNzE4NTYsImxhc3RfdmFsdWUiOiIyNjMwNzE4NTYifQ==",
          "node": {
            "title": "Storefront Shoes"
          }
        }
      ]
    }
  }
  ```

* ### Retrieve product that matches the query

  #### Description

  The following example shows how to query product that matches the query.

  #### Query

  ```graphql
  query getProducts($first: Int, $query: String) {
    products(first: $first, query: $query) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($first: Int, $query: String) { products(first: $first, query: $query) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($first: Int, $query: String) {
      products(first: $first, query: $query) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($first: Int, $query: String) {
      products(first: $first, query: $query) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjo1Mzg4MjUyNjEsImxhc3RfdmFsdWUiOiI1Mzg4MjUyNjEifQ==",
          "node": {
            "title": "Guitar"
          }
        }
      ]
    }
  }
  ```

* ### Retrieve products after sorting by a key

  #### Description

  The following example shows how to query products after sorting by a key.

  #### Query

  ```graphql
  query getProducts($first: Int, $sortKey: ProductSortKeys) {
    products(first: $first, sortKey: $sortKey) {
      edges {
        cursor
        node {
          title
        }
      }
    }
  }
  ```

  #### cURL

  ```bash
  curl -X POST \
  https://your-development-store.myshopify.com/api/2026-04/graphql.json \
  -H 'Content-Type: application/json' \
  -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \
  -d '{
  "query": "query getProducts($first: Int, $sortKey: ProductSortKeys) { products(first: $first, sortKey: $sortKey) { edges { cursor node { title } } } }"
  }'
  ```

  #### React Router

  ```javascript
  import { unauthenticated } from "../shopify.server";

  export const loader = async () => {
    const { storefront } = await unauthenticated.storefront(
      'your-development-store.myshopify.com'
    );
    const response = await storefront.graphql(
      `#graphql
    query getProducts($first: Int, $sortKey: ProductSortKeys) {
      products(first: $first, sortKey: $sortKey) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
    );
    const json = await response.json();
    return json.data;
  }
  ```

  #### Node.js

  ```javascript
  const client = new shopify.clients.Storefront({
    domain: 'your-development-store.myshopify.com',
    storefrontAccessToken,
  });
  const data = await client.query({
    data: `query getProducts($first: Int, $sortKey: ProductSortKeys) {
      products(first: $first, sortKey: $sortKey) {
        edges {
          cursor
          node {
            title
          }
        }
      }
    }`,
  });
  ```

  #### Response

  ```json
  {
    "products": {
      "edges": [
        {
          "cursor": "eyJsYXN0X2lkIjo5Mjk4OTg0NjUsImxhc3RfdmFsdWUiOiJDYW1wZXIgVmFuIn0=",
          "node": {
            "title": "Camper Van"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjo1Mzg4MjUyNjEsImxhc3RfdmFsdWUiOiJHdWl0YXIifQ==",
          "node": {
            "title": "Guitar"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjoyNjMwNzE4NTYsImxhc3RfdmFsdWUiOiJTdG9yZWZyb250IFNob2VzIn0=",
          "node": {
            "title": "Storefront Shoes"
          }
        },
        {
          "cursor": "eyJsYXN0X2lkIjo2NTcyMTE2NSwibGFzdF92YWx1ZSI6IlN0b3JlZnJvbnQgU3Bvb24ifQ==",
          "node": {
            "title": "Storefront Spoon"
          }
        }
      ]
    }
  }
  ```
