I have a Plus client with custom payment options, shipping rules, messaging, and styling in checkout - which all works fine…99% of the time.
However, after going live, it would appear that there are certain scenarios that throw a monkey wrench into all of it.
Specifically, when a user enters a discount code and clicks “Apply”, there’s partial refresh of the page, and it’s breaking the checkout.
Basically, when a discount code is added, and user clicks “apply”, it doesn’t do a full page refresh (a la location.reload), but instead only refreshes part of the page - which appear to be the sections that might be effected by the introduction of a discount code only. Problem being, without a full refresh, the scripts that checkout is reliant upon for creating and adding/removing different elements isn’t loaded with it, which breaks checkout. It’s more than a styling issue, because it is, at times, exposing payment options that cannot be offered for the items present in checkout at that time, which is creating legal, and customer service issues.
My question is this: Is there a state change to listen for when a discount code is added? Or when the partial refresh is complete? Or anything I can listen for in order to trigger full page reload? Mutation Observer has timing issues that make it ineffective in this particular scenario, so my hope is that there is some sort of indicator exposed that can signal a need to reload the page.
Shopify’s native checkout content should refresh fine with this feature. If you have custom JS/HTML, you’ll likely need to generate/wrap it in the change event like so:
Unfortunately eventlisteners/document.on/observer.observe and the like don’t seem to be firing in an an effective way for this specific instance - for the most part, they’re firing too early. That’s kind of why I was hoping someone might know of a slick little state condition that I hadn’t thought of, or had not already explored.
I don’t really use jQuery very often these days, so I’m not sure I wan’t to add that much bloat to an already overweight codebase, but the concepts behind it make sense, and is worth consideration. Especially if it’s proven effective for you in (relatively) similar circumstances, so thank you very much for your insight, I really do appreciate it.
And yes, you are correct, one would typically want to use scripts for some of the operations I’m dealing with. The stability of shopify scripts is vastly superior, relative to standard DOM manipulation, and if it were a simple case of “…just do this/that…” then it would be a done deal. But, alas (and much to my chagrin), this particular project is rather unique with a lot of moving parts and inter-dependent conditions that need to adjust on the fly. So here we are…
jQuery is already loaded in the Checkout as part of the Checkout object (Checkout.$) so you aren’t really adding any extra bloat. I’m also not really a fan of jQuery but the page:change event snippet provided by the Shopify docs is usually the most effective way of doing this and you can still use vanilla JS within if you prefer.
You might also be able to write a vanilla event listener that listens for the page:change event. I believe the advantage of using the jQuery snippet above is that you can initialize multiple event listeners in a single action (‘page:load page:change’), where with vanilla JS you’ll have to do them separately.
It looks like page:load/page:change are custom events triggered by Shopify when the checkout content is ready, so they may be more suitable than other listeners/mutation observer.
Assuming forcing a standard refresh is out of the question
It should be considered to have those options set to be disabled/invisible by default until the javascript allows it so situations like this are moot.
If that’s done test for any FOUC issues needing nicer transitions.
An alternative for lowering incidents is by setting discounts in the /cart though that can be a no-go for any conflicts with checkout-scripts or set expectations of pricing-discounts presentment during checkout.
A really out there untested & theoretical maybe possible kinda sorta solution for checkout customization problems like this is a reload sleight of hand using dom to canvas to screenshot https://community.shopify.com/post/1383208
Haha, so funny. I was going to say that I took the solution you suggested for a test drive last night and saw that jQuery is baked into checkout! haha why does that NOT surprise me?
Anyway, that seems to have done the trick. A little massaging was needed, but in the end that’s gonna work. What I did was create a new script file, wrapped the relevant original code in the “page:change” event listener, and included it at the bottom of checkout.liquid.
Honestly, the fact that I didn’t already know about that checkout feature is probably the most irritating thing about the whole affair…sheesh.
Thank you for your suggestion. I really appreciate it.
I actually thought about adding a css display rule to the offending payment methods, but quickly realized that it would just add another little detail someone would need to account for in the future. I ended up leveraging the Shopify flavor of jQuery that’s baked into the checkout and wrapped the needed code in one of the custom event listeners that is built into it. I’d normally not even bother with jQuery, but since it’s already included in checkout, it was actually very useful in this scenario.