diff --git a/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx
index d4657e798f..e75f19bfb5 100644
--- a/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx
+++ b/www/apps/resources/app/storefront-development/products/price/examples/sale-price/page.mdx
@@ -1,14 +1,52 @@
+---
+sidebar_position: 2
+sidebar_label: "Example: Show Sale Price"
+---
+
export const metadata = {
- title: `React Example: Show Product Variant's Sale Price`,
+ title: `Example: Show Product Variant's Sale Price`,
}
# {metadata.title}
-This document provides an example of how to show a product variant's sale price.
+In this document, you'll learn how to display a product variant's sale price, with a full React example.
-To check if a product variant's price is a sale price, check whether the variant's `calculated_price.calculated_price.price_list_type` field is equal to `sale`.
+## Check if a Price is a Sale
-In that case, the original price is in the variant's `calculated_price.original_amount` field.
+To check if a product variant's price is a sale price, check whether the variant's `calculated_price.calculated_price.price_list_type` field is equal to `sale`:
+
+```ts
+const isSale = selectedVariantPrice.calculated_price.calculated_price.price_list_type === "sale"
+```
+
+Where `selectedVariantPrice` is either the variant the customer selected or the cheapest variant.
+
+---
+
+## Display Original and Discount Amounts
+
+If the price is a sale price, the original price is in the variant's `calculated_price.original_amount` field:
+
+```ts
+const salePrice = formatPrice(selectedVariantPrice.calculated_price.calculated_amount)
+const originalPrice = formatPrice(selectedVariantPrice.calculated_price.original_amount)
+const discountedAmount = formatPrice(
+ selectedVariantPrice.calculated_price.original_amount -
+ selectedVariantPrice.calculated_price.calculated_amount
+)
+```
+
+You can use the original price either to display it or calculate and display the discounted amount.
+
+
+
+Learn more about the `formatPrice` function in [this guide](../show-price/page.mdx#price-formatting)
+
+
+
+---
+
+## Full React Example
For example, in a React-based storefront:
@@ -93,7 +131,7 @@ export default function Product({ params: { id } }: Params) {
.format(amount)
}
- const variantPrice = useMemo(() => {
+ const selectedVariantPrice = useMemo(() => {
if (selectedVariant) {
return selectedVariant
}
@@ -107,22 +145,22 @@ export default function Product({ params: { id } }: Params) {
}, [selectedVariant, product])
const price = useMemo(() => {
- if (!variantPrice) {
+ if (!selectedVariantPrice) {
return
}
// @ts-ignore
- return formatPrice(variantPrice.calculated_price.calculated_amount)
- }, [variantPrice])
+ return formatPrice(selectedVariantPrice.calculated_price.calculated_amount)
+ }, [selectedVariantPrice])
const isSale = useMemo(() => {
- if (!variantPrice) {
+ if (!selectedVariantPrice) {
return false
}
// @ts-ignore
- return variantPrice.calculated_price.calculated_price.price_list_type === "sale"
- }, [variantPrice])
+ return selectedVariantPrice.calculated_price.calculated_price.price_list_type === "sale"
+ }, [selectedVariantPrice])
const originalPrice = useMemo(() => {
if (!isSale) {
@@ -130,8 +168,8 @@ export default function Product({ params: { id } }: Params) {
}
// @ts-ignore
- return formatPrice(variantPrice.calculated_price.original_amount)
- }, [isSale, variantPrice])
+ return formatPrice(selectedVariantPrice.calculated_price.original_amount)
+ }, [isSale, selectedVariantPrice])
return (
@@ -188,9 +226,3 @@ In this example, you:
- Define an `isSale` memo variable that determines whether the chosen variant's price is a sale price. You do that by checking if the value of the variant's `calculated_price.calculated_price.price_list_type` field is `sale`.
- Define an `originalPrice` memo variable that, if `isSale` is enabled, has the formatted original price of the chosen variant. The variant's original price is in the `calculated_price.original_amount` field.
- If `isSale` is enabled, show a message to the customer indicating that this product is on sale along with the original price.
-
-
-
-Learn more about the `formatPrice` function in [this guide](../show-price/page.mdx#price-formatting)
-
-
\ No newline at end of file
diff --git a/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx
index 97ade25085..c38606c715 100644
--- a/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx
+++ b/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx
@@ -1,9 +1,48 @@
+---
+sidebar_position: 1
+sidebar_label: "Example: Show Variant's Price"
+---
+
export const metadata = {
- title: `React Example: Show Product Variant's Price`,
+ title: `Example: Show Product Variant's Price`,
}
# {metadata.title}
+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:
+
+```ts
+const price = formatPrice(
+ selectedVariantPrice.calculated_price.calculated_amount
+)
+```
+
+You'll learn about the `formatPrice` function in the next section.
+
+---
+
+## Price Formatting
+
+To format the price, use JavaScript's [NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) utility. You pass it the amount and the currency code (which you retrieve from the selected region):
+
+```ts
+const formatPrice = (amount: number): string => {
+ return new Intl.NumberFormat("en-US", {
+ style: "currency",
+ currency: region.currency_code,
+ })
+ .format(amount)
+}
+```
+
+---
+
+## Full React Example
+
The following React-based storefront example retrieves the product's price based on the selected variant:
@@ -19,7 +58,7 @@ export const priceHighlights = [
["26", "queryParams", "Build the pricing query parameters."],
["58", "formatPrice", "A utility function to format an amount with its currency."],
["59", `"en-US"`, "If you use a different locale change it here."],
- ["66", "variantPrice", "Assign the variant to compute its price, which is either the selected or cheapest variant."],
+ ["66", "selectedVariantPrice", "Assign the variant to compute its price, which is either the selected or cheapest variant."],
["68", "selectedVariant", "Use the selected variant for pricing."],
["71", "", "If there isn't a selected variant, retrieve the variant with the cheapest price."],
["79", "price", "Compute the price of the selected or cheapest variant."],
@@ -46,7 +85,7 @@ export default function Product({ params: { id } }: Params) {
HttpTypes.StoreProduct | undefined
>()
const [selectedOptions, setSelectedOptions] = useState>({})
- const { region } = useRegion
+ const { region } = useRegion()
useEffect(() => {
if (!loading) {
@@ -93,7 +132,7 @@ export default function Product({ params: { id } }: Params) {
.format(amount)
}
- const variantPrice = useMemo(() => {
+ const selectedVariantPrice = useMemo(() => {
if (selectedVariant) {
return selectedVariant
}
@@ -107,13 +146,13 @@ export default function Product({ params: { id } }: Params) {
}, [selectedVariant, product])
const price = useMemo(() => {
- if (!variantPrice) {
+ if (!selectedVariantPrice) {
return
}
// @ts-ignore
- return formatPrice(variantPrice.calculated_price.calculated_amount)
- }, [variantPrice])
+ return formatPrice(selectedVariantPrice.calculated_price.calculated_amount)
+ }, [selectedVariantPrice])
return (
@@ -173,17 +212,3 @@ In the example above, you:
- 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.
-
-### Price Formatting
-
-To format the price, use JavaScript's [NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) utility. You pass it the amount and the currency code (which you retrieve from the selected region):
-
-```ts
-const formatPrice = (amount: number): string => {
- return new Intl.NumberFormat("en-US", {
- style: "currency",
- currency: region.currency_code,
- })
- .format(amount)
-}
-```
\ No newline at end of file
diff --git a/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx b/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx
new file mode 100644
index 0000000000..dbc5af259c
--- /dev/null
+++ b/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx
@@ -0,0 +1,253 @@
+---
+sidebar_position: 3
+sidebar_label: "Example: Show Price with Taxes"
+---
+
+export const metadata = {
+ title: `Example: Show Product Variant's Price with Taxes`,
+}
+
+# {metadata.title}
+
+In this document, you'll learn how to show a product variant's price with taxes, with a full React example.
+
+## Retrieve Variant's Price with Tax
+
+To retrieve a product variant's price with taxes, you must pass the `region_id` and `country_code` query parameters:
+
+export const fetchHighlights = [
+ ["3", "region_id", "Pass the region ID as a query parameter."],
+ ["4", "country_code", "Pass the ISO 2 country code as a parameter."],
+ ["4", "region.countries[0].iso_2", "You can instead allow the customer to select a specific country."],
+]
+
+```ts highlights={fetchHighlights}
+const queryParams = new URLSearchParams({
+ fields: `*variants.calculated_price`,
+ region_id: region.id,
+ country_code: region.countries[0].iso_2
+})
+
+fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
+ credentials: "include",
+ headers: {
+ "x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
+ },
+})
+.then((res) => res.json())
+.then(({ product }) => {
+ // TODO use product
+ console.log(product)
+})
+```
+
+You pass the selected region's ID and the code of its first country as query parameters to the [Get Product API route](https://docs.medusajs.com/v2/api/store#products_getproductsid).
+
+
+
+You can instead allow the customer to choose their country.
+
+
+
+---
+
+## Display Variant's Price with Taxes
+
+After passing the `region_id` and `country_code` as query parameters when retrieving the product, each variant's price object will have a `calculated_amount_with_tax` property to indicate the price taxes applied:
+
+```ts
+const price = formatPrice(selectedVariantPrice.calculated_price.calculated_amount_with_tax)
+```
+
+Where `selectedVariantPrice` is either the variant the customer selected or the cheapest variant.
+
+
+
+Learn more about the `formatPrice` function in [this guide](../show-price/page.mdx#price-formatting)
+
+
+
+---
+
+## Tax Price Properties
+
+Aside from the `calculated_amount_with_tax` property, a variant's `calculated_price` object has the following properties related to taxes:
+
+1. `calculated_amount_without_tax`: The calculated amount without taxes.
+2. `is_calculated_price_tax_inclusive`: Whether the `calculated_amount` property includes taxes. If enabled, you can display it instead of `calculated_amount_with_tax`.
+
+---
+
+## Full React Example
+
+For example, in a React-based storefront:
+
+
+
+The example passes the `region_id` query parameter for pricing. Learn how to store and retrieve the customer's region in the [Regions guides](../../../../regions/context/page.mdx).
+
+
+
+export const taxHighlight = [
+ ["5", "useRegion", "The `useRegion` hook is implemented in the Region React Context guide."],
+ ["13", "{ params: { id } }: Params", "This is based on Next.js which passes the path parameters as a prop."],
+ ["19", "region", "Access the region using the `useRegion` hook."],
+ ["28", "region_id", "Pass the region ID as a query parameter."],
+ ["29", "country_code", "Pass the ISO 2 country code as a parameter."],
+ ["29", "region.countries[0].iso_2", "You can instead allow the customer to select a specific country."],
+ ["59", "formatPrice", "A utility function to format an amount with its currency."],
+ ["60", `"en-US"`, "If you use a different locale change it here."],
+ ["67", "selectedVariantPrice", "Assign the variant to compute its price, which is either the selected or cheapest variant."],
+ ["69", "selectedVariant", "Use the selected variant for pricing."],
+ ["72", "", "If there isn't a selected variant, retrieve the variant with the cheapest price."],
+ ["80", "price", "Compute the price of the selected or cheapest variant."],
+ ["87", "calculated_amount_with_tax", "Use the variant price's `calculated_amount_with_tax` property to display the price."],
+ ["126", "", "If there's a computed price but no selected variant, show a `From` prefix to the price."],
+ ["127", "price", "Display the computed price."]
+]
+
+```tsx highlights={taxHighlight}
+"use client" // include with Next.js 13+
+
+import { useEffect, useMemo, useState } from "react"
+import { HttpTypes } from "@medusajs/types"
+import { useRegion } from "../providers/region"
+
+type Params = {
+ params: {
+ id: string
+ }
+}
+
+export default function Product({ params: { id } }: Params) {
+ const [loading, setLoading] = useState(true)
+ const [product, setProduct] = useState<
+ HttpTypes.StoreProduct | undefined
+ >()
+ const [selectedOptions, setSelectedOptions] = useState>({})
+ const region = useRegion()
+
+ useEffect(() => {
+ if (!loading) {
+ return
+ }
+
+ const queryParams = new URLSearchParams({
+ fields: `*variants.calculated_price`,
+ region_id: region.id,
+ country_code: region.countries[0].iso_2
+ })
+
+ fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
+ credentials: "include",
+ headers: {
+ "x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
+ },
+ })
+ .then((res) => res.json())
+ .then(({ product: dataProduct }) => {
+ setProduct(dataProduct)
+ setLoading(false)
+ })
+ }, [loading])
+
+ const selectedVariant = useMemo(() => {
+ if (
+ !product?.variants ||
+ !product.options ||
+ Object.keys(selectedOptions).length !== product.options?.length
+ ) {
+ return
+ }
+
+ return product.variants.find((variant) => variant.options?.every(
+ (optionValue) => optionValue.value === selectedOptions[optionValue.option_id!]
+ ))
+ }, [selectedOptions, product])
+
+ const formatPrice = (amount: number): string => {
+ return new Intl.NumberFormat("en-US", {
+ style: "currency",
+ currency: region.currency_code,
+ })
+ .format(amount)
+ }
+
+ const selectedVariantPrice = useMemo(() => {
+ if (selectedVariant) {
+ return selectedVariant
+ }
+
+ return product?.variants?.sort((a: any, b: any) => {
+ return (
+ a.calculated_price.calculated_amount_with_tax -
+ b.calculated_price.calculated_amount_with_tax
+ )
+ })[0]
+ }, [selectedVariant, product])
+
+ const price = useMemo(() => {
+ if (!selectedVariantPrice) {
+ return
+ }
+
+ // @ts-ignore
+ return formatPrice(
+ selectedVariantPrice.calculated_price.calculated_amount_with_tax
+ )
+ }, [selectedVariantPrice])
+
+ return (
+
+ )
+}
+```
+
+In this example, you:
+
+- Pass the selected region's ID and the code of its first country as query parameters to the [Get Product API route](https://docs.medusajs.com/v2/api/store#products_getproductsid).
+ - You can instead allow the customer to choose their country.
+- Display the selected variant's price by formatting its price's `calculated_amount_with_tax` property.
diff --git a/www/apps/resources/app/storefront-development/products/price/page.mdx b/www/apps/resources/app/storefront-development/products/price/page.mdx
index a578faf1e5..379b7900f1 100644
--- a/www/apps/resources/app/storefront-development/products/price/page.mdx
+++ b/www/apps/resources/app/storefront-development/products/price/page.mdx
@@ -10,7 +10,7 @@ In this document, you'll learn how to show a product's variants' prices in the s
## Pricing Query Parameters
-When you retrieve products either with the [List Products](!api!/store#products_getproducts) or [Retrieve Products](!api!/store#products_getproductsid) API routes, you must pass include in the beginning of the `fields` query parameter the value `*variants.calculated_price`.
+When you retrieve products either with the [List Products](!api!/store#products_getproducts) or [Retrieve Products](!api!/store#products_getproductsid) API routes, you must include in the beginning of the `fields` query parameter the value `*variants.calculated_price`.
You also must pass at least one of the following query parameters to retrieve the correct product variant price:
@@ -19,6 +19,29 @@ You also must pass at least one of the following query parameters to retrieve th
- `customer_id`: The ID of the customer viewing the prices. This is useful when you have a promotion or price list overriding a product's price for specific customer groups.
- `customer_group_id`: The ID of the group of the customer viewing the prices. This is useful when you have a promotion or price list overriding a product's price for specific customer groups.
+For example:
+
+```ts
+const queryParams = new URLSearchParams({
+ fields: `*variants.calculated_price`,
+ region_id: region.id,
+})
+
+fetch(`http://localhost:9000/store/products/${id}?${queryParams.toString()}`, {
+ credentials: "include",
+ headers: {
+ "x-publishable-api-key": process.env.NEXT_PUBLIC_PAK || "temp",
+ },
+})
+.then((res) => res.json())
+.then(({ product }) => {
+ // TODO use product
+ console.log(product)
+})
+```
+
+In this example, you pass the selected region's ID as a query parameter with the `fields` query parameter set to `*variants.calculated_price`.
+
---
## Product Variant's Price Properties
@@ -81,9 +104,8 @@ If you pass the parameters mentioned above, each variant has a `calculated_price
----
-
## Examples
-- [React Example: Show Product Variant's Price](./examples/show-price/page.mdx).
-- [React Example: Show Product Variant's Sale Price](./examples/sale-price/page.mdx).
+- [Example: Show Product Variant's Price](./examples/show-price/page.mdx).
+- [Example: Show Product Variant's Sale Price](./examples/sale-price/page.mdx).
+- [Example: Show Product Variant's Price with Taxes](./examples/tax-price/page.mdx).
diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs
index af4fc8c564..8a51b25260 100644
--- a/www/apps/resources/generated/files-map.mjs
+++ b/www/apps/resources/generated/files-map.mjs
@@ -923,6 +923,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/storefront-development/products/price/examples/show-price/page.mdx",
"pathname": "/storefront-development/products/price/examples/show-price"
},
+ {
+ "filePath": "/www/apps/resources/app/storefront-development/products/price/examples/tax-price/page.mdx",
+ "pathname": "/storefront-development/products/price/examples/tax-price"
+ },
{
"filePath": "/www/apps/resources/app/storefront-development/products/price/page.mdx",
"pathname": "/storefront-development/products/price"
diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs
index 0c5c42d56b..651ae5c688 100644
--- a/www/apps/resources/generated/sidebar.mjs
+++ b/www/apps/resources/generated/sidebar.mjs
@@ -6755,12 +6755,13 @@ export const generatedSidebar = [
"isPathHref": true,
"path": "/storefront-development/products/price",
"title": "Retrieve Variant Prices",
+ "autogenerate_path": "storefront-development/products/price/examples",
"children": [
{
"loaded": true,
"isPathHref": true,
"path": "/storefront-development/products/price/examples/show-price",
- "title": "Example: Show Variant Price",
+ "title": "Example: Show Variant's Price",
"children": []
},
{
@@ -6769,6 +6770,13 @@ export const generatedSidebar = [
"path": "/storefront-development/products/price/examples/sale-price",
"title": "Example: Show Sale Price",
"children": []
+ },
+ {
+ "loaded": true,
+ "isPathHref": true,
+ "path": "/storefront-development/products/price/examples/tax-price",
+ "title": "Example: Show Price with Taxes",
+ "children": []
}
]
},
diff --git a/www/apps/resources/sidebar.mjs b/www/apps/resources/sidebar.mjs
index 4cea0413aa..af1d468065 100644
--- a/www/apps/resources/sidebar.mjs
+++ b/www/apps/resources/sidebar.mjs
@@ -1537,16 +1537,7 @@ export const sidebar = sidebarAttachHrefCommonOptions([
{
path: "/storefront-development/products/price",
title: "Retrieve Variant Prices",
- children: [
- {
- path: "/storefront-development/products/price/examples/show-price",
- title: "Example: Show Variant Price",
- },
- {
- path: "/storefront-development/products/price/examples/sale-price",
- title: "Example: Show Sale Price",
- },
- ],
+ autogenerate_path: "storefront-development/products/price/examples",
},
{
path: "/storefront-development/products/categories",