Handling Custom Field Validation for "Add to Cart" and "Buy It Now" Buttons on Shopify Product Page (Theme App Extension)

Hi everyone,

We’re building a Shopify Theme App Extension that injects custom personalization fields (text inputs, dropdowns, image uploads, etc.) into the product page via app blocks.

These fields are dynamically rendered based on metadata, and some are required. Our goal is to validate these required fields before a product is added to cart or the Buy It Now (Shopify Payments) button is triggered.


What We’ve Tried:

  1. Add to Cart:
  • We used JavaScript to listen for the form submission:
const form = document.querySelector('form[action^="/cart/add"]');
form.addEventListener("submit", handleSubmit);
  • In the handleSubmit function, we checked for empty required fields and used:
e.preventDefault();
e.stopImmediatePropagation();
  1. Buy It Now:
  • Since this triggers an AJAX request, we tried attaching a click handler to:
document.querySelector('.shopify-payment-button__button')
  • We also used preventDefault and stopImmediatePropagation, but it sometimes still bypassed validation, especially after a couple of clicks.

The Problem:

  • The validation works intermittently — sometimes preventDefault() doesn’t stop the native Shopify behavior (e.g., the Shopify Checkout popup still opens).
  • Since we don’t control the original form rendering (it’s part of the theme), and the buttons may vary across themes, the selectors and behavior are inconsistent.
  • We’d prefer a reliable way to intercept both Add to Cart and Buy It Now events, perform validation, and prevent submission if any required fields are missing.

What We’re Looking For:

  • A reliable method to validate and block both actions (Add to Cart + Buy It Now) across themes.
  • Ideally using only front-end JavaScript since we cannot modify the native theme liquid form directly.
  • Any best practices for working with Shopify Payment buttons inside theme apps would also be appreciated.

Thanks in advance for any insights!