Product page
It is mandatory to include a product.json
file in the pages
directory.
You can create additional variations such as product.shoes.json
, product.clothes.json
, etc.
Within the Merchant panel, theme users can choose which variation to apply to each product.
Additionally, the product page features a unique data hook, useProduct(), which retrieves the specific product based on the URL.
There are few other hooks available to provide the full functionality of the product page. These are:
useSelectedVariant(), this hook significantly reduces the hassle of variant selection in product pages.
useCartItemQuantity(), this hook lets you add, delete, decrease products in the cart.
Show product details
Use useProduct()
hook to show various details about the product.
import {useProduct} from "builderoo";
const product = useProduct()
Learn more about the useProduct() hook.
Handle option selection
Use the useSelectedVariant()
hook to handle option selection.
As the user selects an option, call onSelectOption()
function. This hook internally keeps track of selection/de-selection of options
and returns the variant
property with the variant value. If there’s no variant available for the combination of the selected options
the value of variant
becomes null
.
import { useProduct, useSelectedVariant} from "builderoo";
// Component
const product = useProduct()
const {variant, onSelectOption, isOptionSelected} = useSelectedVariant(product)
A complete example is available later on this page.
Spotlight the appropriate media
The useSelectedVariant()
hook also returns two other properties.
-
preferredMedia
: As you select options and callonSelectOption
function, thepreferredMedia
contains the media item fromproduct.media
that best matches with the selected options. -
setPreferredMedia
: When the user manually selects a media item, you can usesetPreferredMedia
to set currently spotlighted media item. This method is only provided to avoid complexity in maintaining another state variable to spotlight a media item.
import { useProduct, useSelectedVariant} from "builderoo";
// Component
const product = useProduct()
const {variant, onSelectOption, isOptionSelected, preferredMedia, setPreferredMedia} = useSelectedVariant(product)
Add to cart
Use useCartItemQuantity()
to show how many products are already in the cart,
and to add/delete the product from the cart.
import {useCartItemQuantity} from "builderoo";
const {add, remove, set, count} = useCartItemQuantity(productId, variantId)
// Now add 1 item to the cart
add(1)
// remote the item from the cart
remove()
// set quantity of the product to a specific number
set(3)
Full example
Here’s a full example of using various hooks to make the product page.
import React, {useState} from 'react';
import { useProduct, useCartItemQuantity, useSelectedVariant} from "builderoo";
import classNames from "clsx";
export default function ProductDetail() {
const product = useProduct()
const {variant, onSelectOption, isOptionSelected} = useSelectedVariant(product)
const {add, remove, set} = useCartItemQuantity(product, variant)
const [quantity, setQuantity] = useState(1)
return (
<div>
<section className="px-20 pt-10 grid grid-cols-2 gap-10">
<div className="">
<div>
<img src={product.image} />
</div>
</div>
<div className="flex flex-col">
<h3 className="font-medium text-2xl">{product.title}</h3>
<div className="font-medium text-lg mt-2">{product.price} /></div>
<ul className="space-y-3 mt-4">
{ product.options && product.options.length > 0 && product.options.map((option, i) => (
<li key={i} className="mb-4">
<div className="text-sm text-gray-600 mb-2">{option.name}</div>
<ul className="flex gap-3">
{ option.values.map((value, i) => (
<li
onClick={() => onSelectOption(option._id, value._id)}
key={i}
className={classNames(
"border border-gray-300 rounded-sm px-3 py-1 text-sm cursor-pointer",
{"bg-black text-white": isOptionSelected(option._id, value._id)},
{"bg-muted-background text-black": !isOptionSelected(option._id, value._id)},
)}>
{value.label}
</li>
))}
</ul>
</li>
))}
</ul>
<div className="mt-10 mb-24 flex items-center gap-4">
<button onClick={() => add(1)} disabled={variant == null}>Add to cart</button>
</div>
</div>
</section>
<section className="mt-10 px-20 text-subtle">
{product.description}
</section>
</div>
);
}
Example of the product page using this section:
{
"schema": "https://builderoo.dev/schema/page.json",
"layout": {
"component": "DefaultLayout"
},
"sections": [
{
"component": "ProductDetail"
}
]
}