javascriptbigcommerce

Reliable way of knowing when BigCommerce checkout form has loaded


I'm trying to listen for when the form is loaded on the BigCommerce checkout page. We need to add address validation to the page (+ disable all except first address field so it's auto populated by the address validation service we're using).

The address validation service's JavaScript is firing before the form elements exist because the BigCommerce checkout page works by dynamically adding HTML to the page with JavaScript links which then load the form.

I was thinking of using one of

  1. Polling, setTimeout repeatedly at say 200 millis until some known element exist
  2. Using MutationObserver which seems to do what I want https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver - I can control the div inside which the form is loaded so use mutation ovbserver to listen for "subtree" events but reading the MDN docs it was clear what subtree really means and/or when it fires

Any suggestions?


Solution

  • If you are on Optimized One Page Checkout, you will definitely want to go with the Mutation Listener.

    This Blog Post by the BC team includes some really handy Mutation Listener code that I've leveraged on multiple checkout customizations:

    https://medium.com/bigcommerce-developer-blog/the-complete-guide-to-checkout-customization-on-bigcommerce-6b566bc36fa9

    Word of warning - the OPC checkout is an external application - not included in the base Cornerstone Repo source code at all. I believe it's a React App. If you are familiar with how React and other frameworks handle conditional rendering, they will often un-mount and re-mount components/HTML elements in response to their internal state.

    For example, when you move from the "Shipping Details" step to the "Billing Details" step on checkout, the shipping details DOM nodes are completely un-mounted from the page.

    This means that anything you've attached to them via JS/JQuery, such as event listeners, will be gone. You'll need to configure the mutation listener to listen for mounting of every single section that you need to do work on, not just the entire checkout app. This makes checkout customizations fairly tricky to handle.

    Another issue - if you want to over-write the input field values, you're going to be fighting with the React app, once again. As I've mentioned, React contains an internal state which controls the values of the address inputs. You can try to use JS to change the value of those inputs, but the internal state within the React app corresponding to those fields will not update. You will need to either use the checkout storefrontAPI to update those values,or you will need to use a hacky solution to manually trigger React's internal synthetic event emitter after updating the values with your JS code, I've used this library to some success:

    It's not an ideal solution at all. https://github.com/vitalyq/react-trigger-change

    Preferably, if you need tight control over checkout, you can develop a customized checkout solution using the checkout-sdk that BC provides, but this is not a light task, as it's more a set of building blocks for building custom checkout flows rather than something you can drop in and start customizing right away.