Open schwartzmj opened 4 years ago
Maybe you could redirect users to a custom thank-you page after they complete checkout, and have this page clear your cart.
In Shopify, go to Settings > Checkout, and in the Addition Scripts section, add your redirect URL. (credits to @mister-cairns for this.)
<script type="text/javascript">
var timeout = 6000; // you can change this timeout to your liking.
setTimeout("location.href = 'https://your-url.com/thanks/';", timeout);
</script>
Make a static gastby page (like src/pages/thanks
.) This thank you page will clear the cart on mount.
// src/pages/thanks.tsx
import { useClearCartOnMount } from '../hooks/use-clear-cart-on-mount'
export default function ThankYouPage() {
useClearCartOnMount()
return <div>Thanks for shopping with us!</div>
}
And then the React hook that makes the magic happen:
// src/hooks/use-clear-cart-on-mount.ts
import { useRemoveItemsFromCart, useCartItems } from 'gatsby-theme-shopify-manager'
import { useRef, useEffect } from 'react'
export const useClearCartOnMount = () => {
const items = useCartItems()
const removeItemsFromCart = useRemoveItemsFromCart()
// this is a work-around, since the function isn't memoized
const removeRef = useRef(useRemoveItemsFromCart)
useEffect(() => {
const cartItemVariantIds = items.map((variant) => variant.id)
if (items.length > 0) {
removeRef.current(cartItemVariantIds)
}
}, [items])
}
Since the functions aren't memoized, we'll have to use a useRef
workaround. This work-around avoids infinite loops, ensuring we only clear the cart when the page mounts.
However, as seen by the [items]
dependency in the useEffect
function, we do run the effect again when the items
array changes. We do this since the line items could be fetched asynchronously, and they might not be available on the first useEffect
call.
Finally, if the cart has 0 items (i.e. items.length > 0
doesn't apply), nothing happens.
If a customer completes a checkout but still has the website open in a tab and goes back to the website, they will have a "completed" cart that they cannot get out of until they reload the website.
Interesting. My first thought is that you shouldn't open the checkout in a new window from your custom Gatsby cart. However, this edge case could still happen. You could maybe check if the checkout still exists when the window refocuses, and if not, clear the cart, using the method from above?
I've noticed a "bug" in my use of gatsby-theme-shopify-manager related to the Cart "completedAt" check.
If a customer completes a checkout but still has the website open in a tab and goes back to the website, they will have a "completed" cart that they cannot get out of until they reload the website. This prevents the customer from adding new items to their cart because you cannot add items to a completed cart.
This happens because the only time the cart
completedAt
field is checked is when the app context is initiated (line 45 in ContextProvider.tsx).We may want to add some functionality that checks if the cart is completed/valid before doing certain things like adding items to the cart.