Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cart Item Count not updating when navigating back #18

Open
p6gb opened this issue Apr 16, 2022 · 9 comments
Open

Cart Item Count not updating when navigating back #18

p6gb opened this issue Apr 16, 2022 · 9 comments

Comments

@p6gb
Copy link

p6gb commented Apr 16, 2022

Expected Behavior

When adding an item to the cart and then navigating back (with browser button) the cart should display the number of items including the one that was just added.

Current Behavior

When running on the Shopify server, the cart displays the number of items as it was before adding the last item.
In local environment, the behavior is as expected.

Steps to Reproduce

  1. https://3c4fnxz6hytu2a1b-24813502524.shopifypreview.com
  2. Navigate to Shop
  3. Navigate to a product (most of them are not in stock, but e.g. the fourth one is)
  4. Add to Cart
  5. Navigate back one page with browser button

Context (Environment)

The element that should display the updated count does have the required data-ajax-cart-bind-state="cart.item_count" property.

<span class="cart-count-bubble__count" aria-hidden="true" data-ajax-cart-bind-state="cart.item_count">
  {{ cart.item_count }}</span>

Detailed Info

Shopify's Dawn theme is the basis and it's cart functionality has not (yet) been disabled. Maybe some interference is the reason for this behavior.

@EvgeniyMukhamedjanov
Copy link
Owner

Hey @p6gb
I gave this advice to another Liquid Ajax Cart user maybe it might help you:

I think you take the Dawn theme as a starting point and it has its own JavaScript for updating the cart icon structure.
Try to remove the id="cart-icon-bubble"/Dawn classes to detach the JavaScript logic related to the cart icon and make sure that the data-ajax-cart-bind-state="cart.item_count" element is always there.
I would suggest recreating the icon's structure from scratch without any Dawn classes/id in order not to attach JavaScript from Dawn.
Because it is very difficult to foresee what conflict might happen between Dawn JS and Liquid Ajax Cart JS.

@p6gb
Copy link
Author

p6gb commented Apr 17, 2022

Hey @EvgeniyMukhamedjanov
thanks for your advice. I did that and it seems to work now. All in all I should have built more from scratch but in the beginning I was hesitant because I don't know Shopify too well and didn't want to accidently kill some of Shopifys functionality.

Are you aware of any other components were Dawn and Liquid Ajax Cart JS scripts might interfere? Obviously there is the cart page. I'm thinking to basically have just a blank page there with the floating Liquid Ajax Cart JS always open.

@p6gb
Copy link
Author

p6gb commented Apr 17, 2022

Well, actually I continue to have that problem for mobile.. Can you point me to where the update of the item count happens in the code so i can debug? Is there a load event listener or how does it work?

@p6gb
Copy link
Author

p6gb commented Apr 20, 2022

I continued to have that issue but only when navigating back, especially on mobile devices. It seems that Safari mobile (probably Chrome aswell) serve the cached site for performance reasons and at least in my case there was not even a load event fired. I therefore added a listener on the pageshow event that updates the cart count.

window.addEventListener("pageshow", () => {
  let item_count;
  fetch("/cart.js")
    .then((response) => response.json())
    .then((data) => {
      item_count = data.item_count;
      document.querySelector(".js-cart-count").textContent = item_count;
    });
});

@EvgeniyMukhamedjanov
Copy link
Owner

Sorry for the late answer — didn't have chance to check GitHub. About mobile issue - most likely Dawn using two different element for mobile and desktop. So you need to remove the Dawn JavaScript from mobile version too.
I will be able to give you clear answer only after I make full LAC and Dawn integration.

@p6gb
Copy link
Author

p6gb commented May 3, 2022

Additional HTML Elements are not the problem in my case, it lies with the handling of the bfcache (back/forward-cache) in iOS. When a page is loaded from there by navigating back with the back-button, the load event is not being triggered, but a pageshow event should fire instead. I added a listener to this event and updated the cart then.

However, this works only the first time navigating back and forward again. If you do the same thing twice, the pageload event does not fire again. So far I found no way no way around this except which kills the whole caching and is very ugly. (from here https://stackoverflow.com/a/44194156)

 window.addEventListener('pageshow', function (e) {
    e.persisted &&
      /iPad|iPhone|iPod/.test(navigator.userAgent) &&
      !window.MSStream &&
      window.location.reload();
  }, false);

I've also found several answers suggesting that this behavior comes with having iframe elements on a site. I do have them on that page but don't know if I could remove/disable them because I think Shopify injects them at some point and I wouldn't know how to stop that. And the chat functionality that is a iframe is wanted by the customer.

@p6gb
Copy link
Author

p6gb commented May 3, 2022

Anyways, I think adding something like the following would be a good idea (or is this taken care of otherwise?):

  window.addEventListener("pageshow", (ev) => {
    cartRequestUpdate({}, {});
  });

This should usually work. When I test e.g. here https://back-forward-cache-tester.glitch.me/?persistent_logs=1 the pageshow event fires consistently. I don't really know what the issue is in my case, might have to do with the iframe as I stated above.

@EvgeniyMukhamedjanov
Copy link
Owner

I finally could replicate the issue and understood why it happened. Thanks, @subject-matter
So basically when we click the back button, browser might load the page from cache rather than loading the page normally as if we clicked a link that leads to the page.
When the browser loads a page from cache, it takes the initial HTML of the page, that were there before any Ajax update.
A few similar questions:
https://meta.stackexchange.com/questions/68008/going-back-after-voting-shows-the-page-without-my-vote-in-chrome
https://stackoverflow.com/questions/16431164/preserve-dynamically-changed-html-on-back-button

I'll try to find a workaround for that and let you know.

@EvgeniyMukhamedjanov
Copy link
Owner

The issue is fixed in the v2.0.1 and 1.11.2.
Once a user clicks the back/forward button and if the browser shows the content from cache (thus the wrong cart data shows up), liquid-ajax-cart will send an additional request to update the data.
Let me know if that works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants