Preserving cart contents
In the React-Apollo example, is there any mechanism for preserving cart contents across sessions? If not, what would be the best way to achieve this? Something like https://github.com/elgerlambert/redux-localstorage ?
Oh, but we might also need to send the checkout ID to the server for SSR. So I don't know if Localstorage would work…
🤔 I thought we did but doesn't look like it.
Yeah if you want to do SSR then some sort of server-side storage would be required. Otherwise local storage is the solution.
I guess you could also say that the cart is hidden by default so doesn't need to be SSR'd.
I don't think SSR is necessary here. even if the cart was visible, since cart contents wouldn't impact SEO, which is the main reason for SSR. But I'm still struggling to understand how to implement the cart loading with localStorage in the react-apollo example. Would be great to get an update on this from the team. I'm currently investigating a solution here: https://stackoverflow.com/questions/56682723/manually-fire-a-query-via-compose-graphql/56683016#56683016
I have this working well with localStorage, if I have time to add a PR I will, but our implementation is all with react and apollo hooks so things are a bit different. In the meantime, dropping some code from that working implementation here anyway for whom it may aid...
First off a new bit of gql will need to be added to checkout.js so we may fetch existing checkouts...
export const fetchCheckout = gql`
query($id: ID!) {
node(id: $id) {
...CheckoutFragment
}
}
${CheckoutFragment}
`
The the rest of the magic happens in our react component something like this...
const createNewCheckout = async () => {
const res = await client.mutate({
mutation: createCheckout,
variables: {
input: {},
}
})
return res.data.checkoutCreate.checkout
}
const fetchExistingCheckout = async id => {
const res = await client.query({
query: fetchCheckout,
variables: { id }
})
return res.data.node
}
useEffect(() => {
const initializeCheckout = async () => {
// Check for an existing cart.
const existingCheckoutID = localStorage.getItem("shopify_checkout_id")
const setCheckoutInState = checkout => {
localStorage.setItem("shopify_checkout_id", checkout.id)
setCheckout(checkout)
}
if (existingCheckoutID) {
try {
const checkout = await fetchExistingCheckout(existingCheckoutID)
// Make sure this cart hasn’t already been purchased.
if (!checkout.completedAt) {
setCheckoutInState(checkout)
return
}
} catch (e) {
localStorage.setItem("shopify_checkout_id", null)
}
}
const newCheckout = await createNewCheckout()
setCheckoutInState(newCheckout)
}
initializeCheckout()
}, [])
Kudos to @jlengstorf and https://github.com/gatsbyjs/store.gatsbyjs.org for the insights