- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Menu
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Example: Show Product Variant's Price
In this document, you'll learn how to display a product variant's price with a full React example.
Display Selected Variant Price#
Once the customer selects a variant, use its calculated_price.calculated_amount
property to display its price:
You'll learn about the formatPrice
function in the next section.
Price Formatting#
To format the price, use JavaScript's NumberFormat utility. You pass it the amount and the currency code (which you retrieve from the selected region):
Full React Example#
The following React-based storefront example retrieves the product's price based on the selected variant:
Note: The example only passes the
region_id
query parameter for pricing. Learn how to store and retrieve the customer's region in the Regions guides .1"use client" // include with Next.js 13+2 3import { useEffect, useMemo, useState } from "react"4import { HttpTypes } from "@medusajs/types"5import { useRegion } from "../providers/region"6 7type Params = {8 params: {9 id: string10 }11}12 13export default function Product({ params: { id } }: Params) {14 const [loading, setLoading] = useState(true)15 const [product, setProduct] = useState<16 HttpTypes.StoreProduct | undefined17 >()18 const [selectedOptions, setSelectedOptions] = useState<Record<string, string>>({})19 const { region } = useRegion()20 21 useEffect(() => {22 if (!loading) {23 return 24 }25 26 const queryParams = new URLSearchParams({27 fields: `*variants.calculated_price`,28 region_id: region.id,29 })30 31 fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {32 credentials: "include",33 headers: {34 "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp",35 },36 })37 .then((res) => res.json())38 .then(({ product: dataProduct }) => {39 setProduct(dataProduct)40 setLoading(false)41 })42 }, [loading])43 44 const selectedVariant = useMemo(() => {45 if (46 !product?.variants ||47 !product.options || 48 Object.keys(selectedOptions).length !== product.options?.length49 ) {50 return51 }52 53 return product.variants.find((variant) => variant.options?.every(54 (optionValue) => optionValue.value === selectedOptions[optionValue.option_id!]55 ))56 }, [selectedOptions, product])57 58 const formatPrice = (amount: number): string => {59 return new Intl.NumberFormat("en-US", {60 style: "currency",61 currency: region.currency_code,62 })63 .format(amount)64 }65 66 const selectedVariantPrice = useMemo(() => {67 if (selectedVariant) {68 return selectedVariant69 }70 71 return product?.variants?.sort((a: any, b: any) => {72 return (73 a.calculated_price.calculated_amount -74 b.calculated_price.calculated_amount75 )76 })[0]77 }, [selectedVariant, product])78 79 const price = useMemo(() => {80 if (!selectedVariantPrice) {81 return82 }83 84 // @ts-ignore85 return formatPrice(selectedVariantPrice.calculated_price.calculated_amount)86 }, [selectedVariantPrice])87 88 return (89 <div>90 {loading && <span>Loading...</span>}91 {product && (92 <>93 <h1>{product.title}</h1>94 {(product.options?.length || 0) > 0 && (95 <ul>96 {product.options!.map((option) => (97 <li key={option.id}>98 {option.title}99 {option.values?.map((optionValue) => (100 <button 101 key={optionValue.id}102 onClick={() => {103 setSelectedOptions((prev) => {104 return {105 ...prev,106 [option.id!]: optionValue.value!,107 }108 })109 }}110 >111 {optionValue.value}112 </button>113 ))}114 </li>115 ))}116 </ul>117 )}118 {selectedVariant && (119 <span>Selected Variant: {selectedVariant.id}</span>120 )}121 {price && (122 <span>123 {!selectedVariant && "From: "}124 {price}125 </span>126 )}127 {product.images?.map((image) => (128 <img src={image.url} key={image.id} />129 ))}130 </>131 )}132 </div>133 )134}
In the example above, you:
- Use the
useRegion
hook defined in the previous Region React Context guide. - Pass the pricing query parameters to the request retrieving the product. This retrieves for every variant a new
calculated_price
field holding details about the variant's price. - Choose the variant to show its price:
- If there's a selected variant, choose it.
- If there isn't a selected variant, retrieve and choose the variant with the cheapest price.
- Format the price based on the chosen variant in the previous step. The variant's
calculated_price.calculated_amount
field is used. - Display the formatted price to the customer. If there isn't a select variant, show a
From
label to indicate that the price shown is the cheapest.
Was this page helpful?