Single Product
A single product template renders one Woo product: the product WordPress is currently resolving. Build it with {this.*} and {this.omewoo.*} values.
Minimum Structure
Single product template
CartCount
CartNotices
Product image
Product title
ProductProvider bound to {this.omewoo}
ProductPrice, ProductSku, ProductAvailability, ProductDescription
AddToCartForm
AttributeSelector loop for variable products
AddToCartButton
BuyNowButton
The current product is the WordPress queried object. That makes {this.id}, {this.title}, and {this.omewoo.*} the correct bindings.
Product image: {this.omewoo.media.image.url}
Product title: {this.title}
<OmeWooProductProvider product="{this.omewoo}">
{#slot default}
<OmeWooProductPrice content="{this.omewoo.price.html}" />
<OmeWooProductSku content="{this.omewoo.product.sku}" />
<OmeWooProductAvailability content="{this.omewoo.purchase.availabilityHtml}" />
<OmeWooProductDescription content="{this.omewoo.description.shortHtml}" />
<OmeWooAddToCartForm product='{{"product_id":"{this.id}","product_type":"{this.omewoo.product.type}","variants":{this.omewoo.variants}}}'>
{#slot default}
{#loop this.omewoo.attributes as attribute}
<OmeWooAttributeSelector target='{{"attribute":{attribute}}}' />
{/loop}
<OmeWooAddToCartButton
behavior='{{"mode":"counter","counter_presentation":"stepper","trigger":"form_submit"}}'
quantity='{{"min":"1","max":"3","default":"1"}}'
/>
<OmeWooBuyNowButton content='{{"label":"Buy now"}}' />
{/slot}
</OmeWooAddToCartForm>
{/slot}
</OmeWooProductProvider>
Step 1: Use Current Product Data
| Binding | Meaning |
|---|---|
{this.id} | Current product ID. |
{this.title} | Current product title. |
{this.omewoo.media.image.url} | Main product image URL. |
{this.omewoo.media.image.alt} | Main product image alt text. |
{this.omewoo.price.html} | Server-formatted product price HTML for Product Price. |
{this.omewoo.product.sku} | Base SKU for Product SKU. |
{this.omewoo.purchase.availabilityHtml} | Woo availability HTML for Product Availability. |
{this.omewoo.description.html} / .shortHtml | Full or short base content for Product Description. |
{this.omewoo.product.type} | Product type passed into the form. |
{this.omewoo.attributes} | Attribute objects used by variable product selectors. |
{this.omewoo.variants} | Variation catalogue used by variable product forms. |
Use {this.*} only when the template is actually rendered in a product context. In loops, use {item.*} instead.
Step 2: Build The Purchase Form
Bind ProductProvider.product to the complete {this.omewoo} object. The Provider is a structural shared-state container: choose its root element with structure.tag and style or lay it out through styling.class. It does not replace the form or render product UI by itself.
Place Product Price, SKU, Availability, and Description inside that structural container when they should follow the selected variation. Their content props keep SSR and editor preview useful; the Provider adds runtime synchronization. The readouts do not need to be inside AddToCartForm, because they are derived presentation rather than setters.
AddToCartForm should receive the current product ID and product type:
| Form value | Source |
|---|---|
product_id | {this.id} |
product_type | {this.omewoo.product.type} |
variants | {this.omewoo.variants} for variable products. |
variation_id | Usually empty; selectors resolve selected variation state. |
The add-to-cart button belongs inside the form and should use trigger=form_submit. That keeps simple products, variable products, quantity, add-to-cart, and buy-now behavior on the same payload. Existing standalone forms without ProductProvider remain supported.
Step 3: Add Variation Selectors
For variable products, loop over {this.omewoo.attributes} and place AttributeSelector components inside the form. Each selector writes its selected value into the nearest form. When the product has more than one variation attribute, the form uses {this.omewoo.variants} to resolve the final variation after every required option is selected.
Choose color-swatch or image-swatch for attributes that benefit from a visual choice. Swatches still submit the same exact Woo attribute values and variation IDs as the released select/radio/button modes. Custom visual mappings use scoped CSS on data-ome-value; unresolved mappings keep honest option text. See Color And Image Swatches.
Use VariationResetButton inside the same form when customers need a clear way to reset all attribute choices.
Step 4: Add Quantity And Buy Now
AddToCartButton in counter mode renders a quantity control and submit button. Its default input presentation preserves the released number field. Set behavior.counter_presentation=stepper for decrement, read-only value, and increment controls.
Both presentations edit a local purchase draft; only Add to cart mutates Woo. Stepper presentation inside ProductProvider follows the resolved product or variation's Woo minimum, maximum, step, sold-individually rule, availability, and finite-stock limit. Authored quantity props may tighten those rules. A variation change preserves and normalizes the current stepper draft instead of resetting it, while an unresolved required selection keeps Add disabled. The default input presentation preserves its released integer normalization and authored-limit behavior. See Purchase Draft Quantity.
BuyNowButton also belongs inside AddToCartForm. It serializes the same form payload, adds the product to the cart, then redirects to the authored checkout URL or the localized Woo checkout URL.
Do not use BuyNowButton as a standalone checkout link. Its behavior depends on the parent form state, especially for variable products.
Next References
- Product Purchase lists the purchase component props.
- Data Context and Dynamic Sources explains current-product bindings.
- Woo Dynamic Data Tree lists every
this.omewoofield. - Woo Template Integration Contract explains the
single-productroute.