Version 2025-07 is the last API version to support React-based UI components. Later versions use Polaris web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the upgrade guide to upgrade your extension and avoid being blocked from updating your extension after October 1st 2026.
Storefront API
Querying the Storefront API.
Anchor to StandardApiStandard Api
The base API object provided to purchase extension targets.
- Anchor to queryqueryquery<Data = unknown, Variables = Record<string, unknown>>(query: string, options?: { variables?: Variables; version?: StorefrontApiVersion; }) => Promise<{ data?: Data; errors?: GraphQLError[]; }><Data = unknown, Variables = Record<string, unknown>>(query: string, options?: { variables?: Variables; version?: StorefrontApiVersion; }) => Promise<{ data?: Data; errors?: GraphQLError[]; }>requiredrequired
The method used to query the Storefront GraphQL API with a prefetched token.
Refer to Storefront API access examples for more information.
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.
'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.
{ requestId: string; code: string; } - message
A human-readable description of the error.
string
Examples
Access the Storefront API with query
Description
You can access the [Storefront GraphQL API](/docs/api/storefront) via the `query()` helper function. Ensure your extension can use this API by [enabling the `api_access` capability](/docs/api/checkout-ui-extensions/configuration#api-access).
React
import {useEffect, useState} from 'react'; import { useApi, reactExtension, List, ListItem, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); 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 ( <List> {data?.products?.nodes.map((node) => ( <ListItem key={node.id}> {node.title} </ListItem> ))} </List> ); }JavaScript
import { extension, List, ListItem, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, {query}) => { query<any>( `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); }, );Accessing the Storefront API with fetch()
Description
You can access the [Storefront GraphQL API](/docs/api/storefront) using global `fetch()`. Ensure your extension can access the Storefront API via the [`api_access` capability](/docs/api/checkout-ui-extensions/configuration#api-access). The `shopify:storefront` protocol will automatically infer your Storefront URL and API version declared in your extension config. By omitting the API version (recommended), Shopify will use your API version configured in `shopify.extension.toml`. To change the API version, simply add it to the URL like `shopify:storefront/api/2024-04/graphql.json`. See [Storefront GraphQL API endpoints](/docs/api/storefront#endpoints) for more information.
React
import {useEffect, useState} from 'react'; import { useApi, reactExtension, List, ListItem, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const {shop} = useApi(); const [data, setData] = useState(); useEffect(() => { const getProductsQuery = { query: `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, variables: {first: 5}, }; fetch('shopify:storefront/api/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 ( <List> {data?.products?.nodes.map((node) => ( <ListItem key={node.id}> {node.title} </ListItem> ))} </List> ); }JavaScript
import { extension, List, ListItem, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const getProductsQuery = { query: `query ($first: Int!) { products(first: $first) { nodes { id title } } }`, variables: {first: 5}, }; fetch('shopify:storefront/api/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); }, );