Skip to main content

How Woo Components Work

Woo components have two cooperating layers:

  1. PHP component markup renders the authored Etch block tree, data attributes, slots, preview branches, and server-known dynamic data.
  2. The Woo runtime binds those data attributes, reads Store API state, mutates Woo through Store API endpoints, and updates the same live DOM.

Boot Flow

Woo::maybe_boot() registers the Woo service when WooCommerce is available. The service is triggered by any Woo component key listed in Woo.php, and it localizes:

Localized keyRuntime use
storeApiBaseBase URL for /wc/store/v1 requests.
nonceStore API nonce header.
checkoutUrlFallback redirect target for BuyNowButton.
isAvailable and diagnosticsRuntime availability state.
paymentMethodsSimple enabled payment methods for PaymentMethodSelector.
checkoutFieldsWoo checkout field rules, countries, states, locale overrides, and defaults.

The browser service creates one WooCartStore and one WooCheckoutStore. Cart components subscribe to the cart store. Checkout components subscribe to the checkout store only when checkout UI is present.

SSR and Runtime Updates

The Woo line follows this rule:

SurfaceFirst visible state
Product providers and purchase formsAuthored server markup with product props and optional variation data. Product Provider begins at base-product state.
Cart items and totalsServer dynamic sources when the block tree references cart data, then runtime refresh.
Shipping and payment selectorsServer rows when dynamic sources are available, then runtime normalization and selection binding.
Checkout fieldsServer-authored fields, then runtime applies Woo field schema and country/state logic.
NoticesRuntime feedback regions.

Server markup is not thrown away. The runtime updates text, input values, row state, and cloned rows in place. Templates remain inert blueprints for rows that need to be cloned after a Store API response.

Store API Requests

The cart store sends every mutation through one FIFO coordinator, then refreshes subscribers from the confirmed Store API response:

ActionStore API endpoint
Add itemPOST /cart/add-item
Update quantityPOST /cart/update-item
Remove itemPOST /cart/remove-item
Apply couponPOST /cart/apply-coupon
Remove couponDELETE /cart/coupons?code=...
Select shippingPOST /cart/select-shipping-rate

Shared cart state is never an optimistic draft. It is always the latest cart confirmed by Woo. A quantity input may temporarily show the shopper's local draft while a request is debouncing or queued, but cart rows, counts, totals, coupons, and shipping state continue to read the last confirmed response.

Quantity changes use absolute targets. A short internal 250 ms trailing debounce replaces an unstarted target for the same cart-line key, and at most one newer same-line target waits while a request is in flight. After every response, the coordinator commits that response first, then checks whether the newer target is already satisfied before sending another request. Removing an exact line cancels its unstarted quantity target. The debounce is an internal runtime guarantee; it is not a component prop or public configuration setting.

Operations for different lines and actions keep deterministic FIFO order. Per-line debounce completes before quantity work enters that lane, so a ready unrelated action does not wait behind a draft timer. A rejected operation does not poison the lane, so the next valid cart action can continue. An authoritative conflict cancels the remaining quantity intent for that exact line instead of retrying it automatically.

Mutation feedback hooks

Owned controls expose the detailed local phase in data-ome-woo-mutation-phase:

PhaseMeaning
idleThe control has no active local intent.
debouncingA quantity draft is waiting for the internal trailing window.
queuedThe intent is waiting behind earlier cart work.
pendingIts Store API request is in flight.
successThe final meaningful target was confirmed. This state returns to idle after brief feedback.
errorThe final meaningful intent failed; Cart Notices contains the actionable message.

aria-busy is true for debouncing, queued, and pending. Released data-ome-state hooks remain compatible: those three phases map to loading, while success, error, and idle keep their existing values. Use semantic Woo events for integrations; use these data hooks only for local styling.

The checkout store also serializes requests:

ActionStore API endpoint
Load checkoutGET /checkout
Persist fieldsPUT /checkout?__experimental_calc_totals=true
Place orderPOST /checkout

Component Binding Order

WooRuntime.boot() binds Product Providers before their forms and selectors, then settles each Provider after initial selector synchronization. Initialization therefore publishes only the final semantic selection state. The runtime also binds display components, action components, checkout components, and selectors. This order matters because some render callbacks re-bind child actions:

Parent renderFollow-up binding
CartItems row renderBinds item quantity inputs and remove buttons in the rendered rows.
CouponAppliedList row renderBinds coupon remove buttons in the rendered rows.
OrderSummary renderBinds read-only summary rows and any row-level actions that are present.

Composition Rules

ComponentNeeds
ProductProviderA complete {this.omewoo} or {item.omewoo} product object. It renders a structural container with structure.tag and styling.class, provides derived state, and does not own purchase setters.
AddToCartButton with trigger: standaloneA direct product_id prop or a scoped product quantity input. It is ignored when placed inside AddToCartForm; the form owns submission there.
AddToCartButton with trigger: form_submitA parent AddToCartForm; it renders as the form submit control.
BuyNowButtonA parent AddToCartForm; it serializes the form then redirects.
AttributeSelectorA parent purchase form and a bound props.target.attribute object.
Cart item atomsA CartItems row or OrderSummary product row.
CouponRemoveButtonA CouponAppliedList row with a coupon code.
PlaceOrderButtonA parent checkout form scope.

Events

The runtime dispatches bubbling Woo custom events for Provider variation selection, cart boot, add-to-cart, cart item mutations, checkout boot, and checkout submit lifecycle. Read Woo Custom Events for the supported event names, dispatch targets, and detail payload shapes.