Retrieve a Product in the Storefront

Retrieve a product by ID or handle.

On this page

In this guide, you'll learn how to retrieve a product and its details in the storefront.

On Next.js, retrieve from src/lib/data/products.ts with "use server". Pass storeCode first and region_id (resolved from [countryCode]) when you need calculated prices. See Show Products and Build a Next.js Storefront.

ts

tsCopy
"use server"
export const retrieveProduct = async ({
storeCode,
productId,
countryCode,
}: {
storeCode: string
productId: string
countryCode?: string
}): Promise<HttpTypes.StoreProduct> => {
const region = countryCode
? await getRegion(storeCode, countryCode)
: null
const { product } = await sdk.store.product.retrieve(storeCode, productId, {
...(region?.id ? { region_id: region.id } : {}),
fields: region?.id
? "id,title,handle,*variants,*variants.calculated_price,*options,+images"
: "id,title,handle,*variants,*options,+images",
})
return product
}

How to Retrieve a Product in Storefront?

There are two ways to retrieve a product:


Retrieve a Product by ID

To retrieve a product by its ID, send a request to the Retrieve Product API route:

Tip: Learn how to install and configure the JS SDK in the Getting started guide.

React

tsx

tsxCopy
"use client" // include with Next.js 13+
import { useEffect, useState } from "react"
import { HttpTypes } from "@aiminaabeejs/types"
import { sdk } from "@/lib/sdk"
type Props = {
id: string
}
export default function Product({ id }: Props) {
const [loading, setLoading] = useState(true)
const [product, setProduct] = useState<
HttpTypes.StoreProduct | undefined
>()
useEffect(() => {
if (!loading) {
return
}
sdk.store.product.retrieve("us", id)
.then(({ product: dataProduct }) => {
setProduct(dataProduct)
setLoading(false)
})
}, [loading, id])
return (
<div>
{loading && <span>Loading...</span>}
{product && (
<>
<h1>{product.title}</h1>
{(product.options?.length || 0) > 0 && (
<ul>
{product.options!.map((option) => (
<li key={option.id}>
{option.title}
<ul>
{option.values?.map((optionValue) => (
<li key={optionValue.id}>{optionValue.value}</li>
))}
</ul>
</li>
))}
</ul>
)}
{product.images?.map((image) => (
<img src={image.url} alt={product.title} key={image.id} />
))}
</>
)}
</div>
)
}

JS SDK

ts

tsCopy
sdk.store.product.retrieve("us", id)
.then(({ product: dataProduct }) => {
// TODO use the product...
console.log(dataProduct)
})

The response has a product field, which is a product object.

Tip: Refer to the Features in Product Details Page section to learn about other features you can add to a product details page.


Retrieve a Product by Handle

To retrieve a product by its handle, send a request to the List Products API route passing the handle query parameter:

React

tsx

tsxCopy
"use client" // include with Next.js 13+
import { useEffect, useState } from "react"
import { HttpTypes } from "@aiminaabeejs/types"
import { sdk } from "@/lib/sdk"
type Params = {
params: {
handle: string
}
}
export default function Product({ params: { handle } }: Params) {
const [loading, setLoading] = useState(true)
const [product, setProduct] = useState<
HttpTypes.StoreProduct | undefined
>()
useEffect(() => {
if (!loading) {
return
}
sdk.store.product.list("us", {
handle,
})
.then(({ products }) => {
if (products.length) {
setProduct(products[0])
}
setLoading(false)
})
}, [loading, handle])
return (
<div>
{loading && <span>Loading...</span>}
{!loading && !product && <span>Product not found</span>}
{product && (
<>
<h1>{product.title}</h1>
{(product.options?.length || 0) > 0 && (
<ul>
{product.options!.map((option) => (
<li key={option.id}>
{option.title}
<ul>
{option.values?.map((optionValue) => (
<li key={optionValue.id}>{optionValue.value}</li>
))}
</ul>
</li>
))}
</ul>
)}
{product.images?.map((image) => (
<img src={image.url} alt={product.title} key={image.id} />
))}
</>
)}
</div>
)
}

JS SDK

ts

tsCopy
sdk.store.product.list("us", {
handle,
})
.then(({ products }) => {
if (!products.length) {
// Product not found with the specified handle
return
}
// use the product...
console.log(products[0])
})

Retrieve Translated Product

Prerequisites

  • Translation Module Configured

By default, Aiminaabee returns the product's original content (such as title and description).

If you support localization in your storefront, you can set the locale to retrieve product information based on the customer's preferred language.

You can set the locale using one of the following methods:

  • Use the JS SDK's setLocale method. The JS SDK will automatically include the locale in subsequent requests.
  • Pass the locale query parameter to the List Products API route.
  • Set the x-aiminaabee-locale header in the API request to the List Products API route.

For example:

Using JS SDK

ts

tsCopy
sdk.setLocale("fr-FR")
sdk.store.product.retrieve("us", id)
.then(({ product }) => {
// TODO use the product...
console.log(product)
})

Using Query Parameter

bash

bashCopy
curl "http://localhost:3000/store/products/prod_123?locale=fr-FR" \
-H 'x-publishable-api-key: {your_publishable_api_key}'

Using Header

bash

bashCopy
curl "http://localhost:3000/store/products/prod_123" \
-H 'x-publishable-api-key: {your_publishable_api_key}' \
-H "x-aiminaabee-locale: fr-FR"

The returned product will have the same structure as described in the products schema, but fields such as title and description will be in the specified locale:

json

jsonCopy
{
"id": "prod_123",
"title": "Chemise Exemple",
"description": "Ceci est une description en français.",
// other product fields...
}

If translations aren't available for the selected locale, or no locale is selected, the product's original content is returned.

Retrieve in Server-Side Environments

For server-side environments (such as server components or server actions in Next.js), you can set the locale using cookies to persist the selected locale across requests.

Learn more in the Storefront Localization guide.


Features in Product Details Page

On a product details page, you typically want to allow customers to choose a variant, see its price, and add it to the cart.

The following guides will help you add these features to your storefront: