--- title: product - Storefront API description: Fetch a specific `Product` by one of its unique attributes. api_version: 2025-10 api_name: storefront type: query api_type: graphql source_url: html: https://shopify.dev/docs/api/storefront/latest/queries/product md: https://shopify.dev/docs/api/storefront/latest/queries/product.md --- # product query Fetch a specific `Product` by one of its unique attributes. ## Arguments * handle [String](https://shopify.dev/docs/api/storefront/latest/scalars/String) The handle of the `Product`. * id [ID](https://shopify.dev/docs/api/storefront/latest/scalars/ID) The ID of the `Product`. *** ## Possible returns * Product [Product](https://shopify.dev/docs/api/storefront/latest/objects/Product) The `Product` object lets you manage products in a merchant’s store. Products are the goods and services that merchants offer to customers. They can include various details such as title, description, price, images, and options such as size or color. You can use [product variants](https://shopify.dev/docs/api/storefront/latest/objects/ProductVariant) to create or update different versions of the same product. You can also add or update product [media](https://shopify.dev/docs/api/storefront/latest/interfaces/Media). Products can be organized by grouping them into a [collection](https://shopify.dev/docs/api/storefront/latest/objects/Collection). Learn more about working with [products and collections](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/products-collections). *** ## Examples * ### Load products which are published in a given context #### Description The Storefront API will automatically limit your query to products that are published in any applicable catalogs. Unpublished products will behave just like they were archived or deleted: they will be omitted from connections and not found when queried by handle or ID. Use the \`@inContext\` directive to set the context explicitly; if omitted, the primary market will be used. > Note: If your app is a sales channel to which products can be published, then the Storefront API will only return products that are published both to your sales channel \_and\_ the market you’re querying for. In this example, the merchant has restricted their alarm clock from sale in the United Kingdom by unpublishing it from that market’s catalog. That product field returns \`null\` and that product is not included in the \`products\` connection response. #### Query ```graphql query Products @inContext(country: GB) { woolSweater: product(handle: "wool-sweater") { title } alarmClock: product(handle: "alarm-clock") { title } products(first: 2) { nodes { title } } } ``` #### cURL ```bash curl -X POST \ https://your-development-store.myshopify.com/api/2025-10/graphql.json \ -H 'Content-Type: application/json' \ -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \ -d '{ "query": "query Products @inContext(country: GB) { woolSweater: product(handle: \"wool-sweater\") { title } alarmClock: product(handle: \"alarm-clock\") { title } products(first: 2) { nodes { 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 Products @inContext(country: GB) { woolSweater: product(handle: "wool-sweater") { title } alarmClock: product(handle: "alarm-clock") { title } products(first: 2) { nodes { 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 Products @inContext(country: GB) { woolSweater: product(handle: "wool-sweater") { title } alarmClock: product(handle: "alarm-clock") { title } products(first: 2) { nodes { title } } }`, }); ``` #### Response ```json { "woolSweater": { "title": "Wool sweater" }, "alarmClock": null, "products": { "nodes": [ { "title": "Wool sweater" } ] } } ``` * ### Load translated and localized content for a product #### Description By adding the \`@inContext\` directive to your query, you can access localized and translated content. #### Query ```graphql query ProductTitle @inContext(country: CA, language: FR) { product(handle: "wool-sweater") { title description } } ``` #### cURL ```bash curl -X POST \ https://your-development-store.myshopify.com/api/2025-10/graphql.json \ -H 'Content-Type: application/json' \ -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \ -d '{ "query": "query ProductTitle @inContext(country: CA, language: FR) { product(handle: \"wool-sweater\") { title description } }" }' ``` #### 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 ProductTitle @inContext(country: CA, language: FR) { product(handle: "wool-sweater") { title description } }`, ); 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 ProductTitle @inContext(country: CA, language: FR) { product(handle: "wool-sweater") { title description } }`, }); ``` #### Response ```json { "product": { "title": "Chandail en laine", "description": "C’est très chaud!" } } ``` * ### Retrieve local prices for a product #### Description By adding the \`@inContext\` directive to your query, you can access local pricing for a specified country. These prices are returned in the currency configured for the country in Markets settings. They may be calculated from the base variant prices, or provided by the merchant as fixed local prices. #### Query ```graphql query ProductPricing @inContext(country: CA) { product(handle: "wool-sweater") { variants(first: 1) { nodes { price { amount currencyCode } } } } } ``` #### cURL ```bash curl -X POST \ https://your-development-store.myshopify.com/api/2025-10/graphql.json \ -H 'Content-Type: application/json' \ -H 'X-Shopify-Storefront-Access-Token: {storefront_access_token}' \ -d '{ "query": "query ProductPricing @inContext(country: CA) { product(handle: \"wool-sweater\") { variants(first: 1) { nodes { price { amount currencyCode } } } } }" }' ``` #### 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 ProductPricing @inContext(country: CA) { product(handle: "wool-sweater") { variants(first: 1) { nodes { price { amount currencyCode } } } } }`, ); 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 ProductPricing @inContext(country: CA) { product(handle: "wool-sweater") { variants(first: 1) { nodes { price { amount currencyCode } } } } }`, }); ``` #### Response ```json { "product": { "variants": { "nodes": [ { "price": { "amount": "90.0", "currencyCode": "CAD" } } ] } } } ``` [Open in GraphiQL](http://localhost:3457/graphiql?query=query%20Products%20%40inContext\(country%3A%20GB\)%20%7B%0A%20%20woolSweater%3A%20product\(handle%3A%20%22wool-sweater%22\)%20%7B%0A%20%20%20%20title%0A%20%20%7D%0A%20%20alarmClock%3A%20product\(handle%3A%20%22alarm-clock%22\)%20%7B%0A%20%20%20%20title%0A%20%20%7D%0A%20%20products\(first%3A%202\)%20%7B%0A%20%20%20%20nodes%20%7B%0A%20%20%20%20%20%20title%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D) ```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 Products @inContext(country: GB) { woolSweater: product(handle: "wool-sweater") { title } alarmClock: product(handle: "alarm-clock") { title } products(first: 2) { nodes { title } } }`, ); const json = await response.json(); return json.data; } ``` ## Response JSON ```json { "woolSweater": { "title": "Wool sweater" }, "alarmClock": null, "products": { "nodes": [ { "title": "Wool sweater" } ] } } ```