Bricks version: 2.4-beta
Symptom: A checkout built the common way — one order summary inside a collapsible panel for small screens, another in the sticky right column for large ones, each shown by a breakpoint — updates only one of them. Whichever instance is second in the DOM keeps whatever it rendered at page load. Applying a coupon appears to do nothing until the page is reloaded.
It is not specific to coupons: the same fragment carries every updated_checkout, so choosing a shipping method, entering an address that changes the tax, or editing a quantity also leaves the visible summary showing a total the customer will not be charged. On mobile that is the only summary they see.
Root cause: the element is a singleton at both ends.
includes/woocommerce/elements/woocommerce-checkout-order-summary.phpforces a fixed root id on every instance:
$this->set_attribute( '_root', 'id', 'bricks-woo-checkout-order-summary' );
$this->attributes['_root']['id'] = 'bricks-woo-checkout-order-summary';
so two summaries produce two elements with the same id (also invalid HTML).
includes/woocommerce.php::update_order_review_fragments()stops at the first matching element (is_null( $checkout_order_root )) and registers the fragment under that id:
$fragments['#bricks-woo-checkout-order-summary'] = \Bricks\Frontend::render_data( $checkout_order_summary_elements );
WooCommerce’s checkout.js then runs $( key ).replaceWith( value ). jQuery resolves a bare #id through getElementById, so exactly one node is replaced regardless of how many share the id.
Note on the obvious fix: switching to a class selector — the way the neighbouring fragments in the same method already do for .brxe-woocommerce-shipping-options and .brxe-woocommerce-payment-options — is not enough here. Those instances share one markup blob, whereas two summaries are two different subtrees whose styling is keyed on their own .brxe-{id}. Replacing both with one rendered blob would give one instance the other’s markup and styling. The fragment has to be produced per instance.
Fix suggestion: drop the forced shared id, keep each instance addressable by something unique (its own .brxe-{id} is already there), and in update_order_review_fragments() loop over every woocommerce-checkout-order-summary element instead of breaking at the first, emitting one fragment per instance.
Workaround we’re using: a filter on woocommerce_update_order_review_fragments at priority 20 that stamps each instance with a class derived from its Bricks element id (via bricks/element/render_attributes), renders each subtree with \Bricks\Woocommerce::extract_element_data_from_root() + \Bricks\Frontend::render_data(), emits one fragment per instance and unsets the native #bricks-woo-checkout-order-summary key. Confirmed working on 375px and 1280px across repeated apply/remove cycles.