Skip to main content

September 7, 2026

Centra PDP add to cart stays pressable

A fashion PDP that greys out add to cart until size is picked looks broken. Validate on submit, show the hint after a miss, then focus the chips.

Sander Korf4 min read

A Centra fashion product page has size chips, a primary purchase button, and a sticky bar that follows you on mobile while you scroll the gallery. Shoppers add from the product info block or from that bar without hunting the original CTA. The old pattern disabled the primary button until a size was chosen. Sometimes the label flipped to Choose size and the button did nothing useful. People tap once, assume the site is broken, and leave.

I used to treat a disabled CTA as honest. You cannot add a tee without a size, so grey it out. Fashion shoppers do not read disabled states that way. They see a big button that ignores them. On a sticky bar it is worse: the control sits in their thumb's way, it looks like the buy action, and it still swallows the tap.

In the demo below, press Add to cart with no size selected. The hint should appear only after the miss, the variant sheet should open, and focus should land on the size row (not a dead button). Pick a size chip and watch the hint clear on that tap alone. You do not need another submit to dismiss the error; the next add-to-cart press is when you actually send the line item.

Interactive

Validate size on submit, not on render

The primary button stays pressable. Tap Add to cart without a size to set the error, show the hint, and open the variant sheet.

Size

Hint renders only when multiSize && sizeRequiredError && !sizeSelected. No reserved empty space before the first miss.

Split enablement from validation

The new pattern splits enablement from validation. primaryEnabled ignores missing size. It still respects pending state, hard disabled flags, and notify mode, because those are real reasons the shop cannot take the tap. The label can still read Choose size. The button stays clickable.

ProductPurchaseSelectionProvider keeps sizeRequiredError. submitAddToCart with no size sets the error and returns early. Picking a size clears it. The red hint renders only when multiSize && sizeRequiredError && !sizeSelected. No invisible reserved space before the first miss. I don't park a blank error slot "just in case." That slot shoves the sticky bar and looks like a layout bug on a clean PDP.

Why disable-until-size fails

I shipped disabled={!sizeSelected} plus a label change first. Checkout forms do that for required fields. On a fashion PDP it trained people that the primary control is decorative. Sticky bars made it worse because the shopper already committed to buying. They are not browsing the size row. They press the thing that says Add to cart. If it does not respond, they don't go hunting for chips. They bounce.

Notify mode still goes through primaryEnabled. Out-of-stock is a different purchase path, with its own label and icon. Missing size is a recoverable miss. Those two should not share a disabled flag. Copy primaryEnabled = true into an OOS row and you will add nothing, notify no one, and still look broken.

Sticky bar wiring matters on mobile. Press add with no size: call submitAddToCart (sets the error), open the variant sheet, then focusSizeControl() through a ProductStickyCartSizeFocusTarget ref registered on the size control. The shopper lands on the chips instead of hunting for why nothing happened.

If you only set the error and never focus, the hint can render above a sheet the shopper is not looking at. If you only open the sheet and never set the error, they get chips with no explanation. The submit path has to do both.

ProductInfoActions went presentational. Parent passes cartLabel, primaryEnabled, primaryIcon, and showSizeRequiredHint. resolvePrimaryPurchaseUiState centralizes notify mode, icons, and hint visibility so PDP, sticky bar, and quick add share one truth. Three slightly different disabled rules is how the sticky bar and the main CTA disagree on the same SKU.

Add all needs a lock too

Shop the Look on the same PDP can add several pinned SKUs at once. Add to cart accepts item arrays under one lock so parallel pin adds from Add all do not race Centra line creation. Validation on one SKU and a fan-out add are different shapes. They both fail the same way if two submits mutate the cart at once.

This pattern assumes a size row you can focus. Single-size products skip the hint because multiSize is false. Notify mode still owns enablement when stock says you cannot add. Don't lift the clickable-button trick into every purchase state and call it done.

Validation on submit beats a permanently disabled CTA. Tell people what went wrong when they try, not before they care.


Happy coding! Sander