--- title: Storefront API description: >- The Storefront API lets you query the GraphQL Storefront API to read product, collection, and other storefront data from within your extension. Use this API to display product recommendations, look up collection details, or fetch any publicly available storefront information. api_version: 2025-07 api_name: customer-account-ui-extensions source_url: html: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/target-apis/platform-apis/storefront-api md: >- https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/target-apis/platform-apis/storefront-api.md --- Migrate to Polaris Version 2025-07 is the last API version to support React-based UI components. Later versions use [web components](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/polaris-web-components), native UI elements with built-in accessibility, better performance, and consistent styling with [Shopify's design system](https://shopify.dev/docs/apps/design). Check out the [migration guide](https://shopify.dev/docs/apps/build/customer-accounts/migrate-to-web-components) to upgrade your extension. # Storefront API The Storefront API lets you query the [GraphQL Storefront API](https://shopify.dev/docs/api/storefront) to read product, collection, and other storefront data from within your extension. Use this API to display product recommendations, look up collection details, or fetch any publicly available storefront information. This API requires the `api_access` [capability](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07#configuration). Enable it under `[extensions.capabilities]` in your extension's configuration. For customer and order data, use the [Customer Account API](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/target-apis/account-apis/customer-account-api). ### Use cases * **Display product recommendations**: Query products by collection or tag and render personalized suggestions on customer account pages. * **Show order-related products**: Fetch product details for items in a customer's order to display warranty information, care instructions, or upsell opportunities. * **Build collection browsers**: Query collections to let customers browse and save products directly from a full-page extension. * **Enrich extension content with storefront data**: Pull product images, descriptions, and pricing to create rich, data-driven extension experiences. ### Support Targets (25) ### Supported targets * Customer​Account::Kitchen​Sink * [customer-account.​footer.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/footer#footer-render-after-) * [customer-account.​order-index.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-targets) * [customer-account.​order-index.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-index#order-index-block-) * [customer-account.​order-status.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-announcement-) * [customer-account.​order-status.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#order-status-block-) * [customer-account.​order-status.​cart-line-item.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-item-render-after-) * [customer-account.​order-status.​cart-line-list.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#cart-line-list-render-after-) * [customer-account.​order-status.​customer-information.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-status#customer-information-render-after-) * [customer-account.​order-status.​fulfillment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#fulfillment-status-targets) * [customer-account.​order-status.​payment-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#payments-and-returns-targets) * [customer-account.​order-status.​return-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/payments-and-returns#return-details-render-after-) * [customer-account.​order-status.​unfulfilled-items.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/fulfillment-status#unfulfilled-items-render-after-) * [customer-account.​order.​action.​menu-item.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-menu-item-) * [customer-account.​order.​action.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/order-actions#order-action-) * [customer-account.​order.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#order-specific-full-page-) * [customer-account.​page.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/full-page#customer-account-full-page-) * [customer-account.​profile.​addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-page-default-targets-) * [customer-account.​profile.​announcement.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#announcement-) * [customer-account.​profile.​block.​render](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-default#profile-block-) * [customer-account.​profile.​company-details.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#profile-page-b2b-targets-) * [customer-account.​profile.​company-location-addresses.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-addresses-render-after-) * [customer-account.​profile.​company-location-payment.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-payment-render-after-) * [customer-account.​profile.​company-location-staff.​render-after](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07/targets/profile-page-b2b#company-location-staff-render-after-) * customer-account.​profile.​payment.​render-after ### Properties The Storefront API object provides the query interface for the GraphQL Storefront API. Access the following properties on the API object to fetch product, collection, and other storefront data. * **query** **\(query: string, options?: { variables?: Variables; version?: StorefrontApiVersion; }) => Promise<{ data?: Data; errors?: GraphQLError\[]; }>** **required** Queries the Storefront GraphQL API using a prefetched token. Requires the [`api_access` capability](https://shopify.dev/docs/api/customer-account-ui-extensions/2025-07#configuration) in your extension configuration. ### StorefrontApiVersion The supported Storefront API versions. Pass one of these values to \`query()\` to target a specific API version when querying the Storefront GraphQL API. ```ts '2022-04' | '2022-07' | '2022-10' | '2023-01' | '2023-04' | '2023-07' | '2024-01' | '2024-04' | '2024-07' | '2024-10' | '2025-01' | '2025-04' | 'unstable' ``` ### GraphQLError An error returned by the Storefront GraphQL API. Contains a human-readable \`message\` and an \`extensions\` object with the request ID and error code for debugging. * extensions Additional error metadata including the request ID and error code. ```ts { requestId: string; code: string; } ``` * message A human-readable description of the error. ```ts string ``` Examples ### Examples * #### Query products with the query helper ##### Description Use the \`shopify.query()\` helper to run a Storefront GraphQL query with variables. This example fetches the first five products and renders their titles in a list. ##### React ```tsx import {useEffect, useState} from 'react'; import { useApi, reactExtension, List, ListItem, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => , ); function Extension() { const [data, setData] = useState(); const {query} = useApi(); useEffect(() => { query( `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, { variables: {first: 5}, }, ) .then(({data, errors}) => setData(data)) .catch(console.error); }, [query]); return ( {data?.products?.nodes.map((node) => ( {node.title} ))} ); } ``` ##### TS ```js import { extension, List, ListItem, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, {query}) => { query( `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, { variables: {first: 5}, }, ) .then(({data}) => { const listItems = data?.products?.nodes.map((node) => root.createComponent( ListItem, undefined, node.title, ), ); root.appendChild( root.createComponent( List, undefined, listItems, ), ); }) .catch(console.error); }, ); ``` * #### Query the GraphQL Storefront API with global fetch ##### Description Use the global \`fetch()\` function to query the GraphQL Storefront API directly. This example fetches products using a POST request and renders the results. ##### React ```tsx import {useEffect, useState} from 'react'; import { reactExtension, List, ListItem, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => , ); function Extension() { const [data, setData] = useState(); useEffect(() => { const getProductsQuery = { query: `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, variables: {first: 5}, }; const apiVersion = 'unstable'; fetch( `shopify://storefront/api/${apiVersion}/graphql.json`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(getProductsQuery), }, ) .then((response) => response.json()) .then(({data, errors}) => setData(data)) .catch(console.error); }, []); return ( {data?.products?.nodes.map((node) => ( {node.title} ))} ); } ``` ##### TS ```js import { extension, List, ListItem, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root) => { const apiVersion = 'unstable'; const getProductsQuery = { query: `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, variables: {first: 5}, }; fetch( `shopify://storefront/api/${apiVersion}/graphql.json`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(getProductsQuery), }, ) .then((response) => response.json()) .then(({data}) => { const listItems = data?.products?.nodes.map((node) => root.createComponent( ListItem, undefined, node.title, ), ); root.appendChild( root.createComponent( List, undefined, listItems, ), ); }) .catch(console.error); }, ); ``` * #### Query a single product by ID ##### Description Pass a product ID as a variable to fetch details for a specific product. This example queries a single product and displays its title and description. ##### React ```tsx import {useEffect, useState} from 'react'; import { reactExtension, useApi, BlockStack, Heading, Text, Spinner, } from '@shopify/ui-extensions-react/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => , ); function Extension() { const {query} = useApi(); const [product, setProduct] = useState(null); useEffect(() => { query( `query ($id: ID!) { product(id: $id) { title description } }`, { variables: { id: 'gid://shopify/Product/1', }, }, ) .then(({data}) => { setProduct(data?.product); }) .catch(console.error); }, [query]); if (!product) { return ; } return ( {product.title} {product.description} ); } ``` ##### TS ```js import { extension, BlockStack, Heading, Text, Spinner, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, {query}) => { const spinner = root.createComponent( Spinner, ); root.appendChild(spinner); query( `query ($id: ID!) { product(id: $id) { title description } }`, { variables: { id: 'gid://shopify/Product/1', }, }, ) .then(({data}) => { const product = data?.product; if (!product) return; root.removeChild(spinner); const heading = root.createComponent( Heading, {}, product.title, ); const text = root.createComponent( Text, {}, product.description, ); const stack = root.createComponent( BlockStack, {}, [heading, text], ); root.appendChild(stack); }) .catch(console.error); }, ); ``` *** ## Best practices * **Prefer `shopify.query()` over raw `fetch()`**: The query helper automatically handles GraphQL Storefront API authentication, versioning, and request formatting. Use `fetch()` only when you need lower-level control over the request. * **Request only the fields you need**: Write targeted GraphQL queries that select specific fields rather than requesting entire objects. This reduces response size and improves extension performance. * **Cache responses when appropriate**: If you're querying data that doesn't change frequently (such as collection metadata), store the result in component state to avoid redundant network requests on re-renders. * **Handle errors and loading states**: Always check for `errors` in the GraphQL response and display appropriate loading indicators while queries are in flight. *** ## Limitations * The `api_access` capability must be enabled in your extension's configuration before you can use this API. Queries will fail without it. * The global `fetch()` approach requires you to manually specify the API version in the URL. If you use an unsupported version, the request will fail. * Query complexity and rate limits from the GraphQL Storefront API still apply. Extensions that issue many concurrent queries may be throttled. ***