Shopify / dawn

Shopify's first source available reference theme, with Online Store 2.0 features and performance built-in.
Other
2.47k stars 3.3k forks source link

Cart notification breaks when using Shopify Scripts, for Shopify Plus #1628

Open MathiasWDN opened 2 years ago

MathiasWDN commented 2 years ago

Describe the current behavior

When applying a Shopify Script that modify the price of a line item(s), the cart notification does not show up.

Describe the expected behavior Cart notification should show up as normal - regardless of using a Shopify Script or not.

Version information (Dawn, browsers and operating systems)

Happens also in Chrome, v. 100

Possible solution It seems that it's a DOM related issue that gives us the error, but investigating further, it seems more like an endpoint issue.

The item.key of the cart item does not match the item.key that the script uses to find the correct cart item to display. This mismatch seems to be caused by the Shopify Script being applied, thus modifying the line item?

This mismatch of item.keys seems to stem from the [..]/cart/add endpoint, which gives the wrong line item property... It seems the cart/add is not aware of the line items being applied, yielding the wrong item.key

The [..]/cart gives us the "correct" item.key.

Additional context/screenshots

I run a Shopify script that reduce line item price based on quantity. Buy 1, get full price. Buy 2, save $4, Buy 3, save $7. The Shopify script for Shopify Plus handles this - so no fancy apps or similar that could interfere. When I disable the script, everything works again.

If I add 1 product, everything's good - and the scripts has not done anything yet. I add 1 more product, and the discount from the Shopify script is applied - and the item.key is changed (!)? 🤔

After the discount is applied the notification breaks. The script keeps looking up a wrong "key" - even after page reloads etc. ([..]/cart/add vs [..]/cart endpoint mismatch)

See attached screenshots for additional examples. The console.warn is the item.key that's being used to find the product in the cart notification. 1 item in cart, vs 2. of the same (w. discount applied).

My solution

I opted for a rather weak solution, which basically checks if an element is found. If not, it'll strip the item.key of it's line item property, and make a weak selector id^= instead of id=, which will give me a matching product - and no page breaking error.

(item.key = [product_id]:[some_hash]).split(':')[0].replaceAll('=', '^=')

Console message

TypeError: null is not an object (evaluating 'new DOMParser().parseFromString(t,"text/html").querySelector(e).innerHTML') 
 cart-notification.js:0
    (anonymous function) (product-form.js:1:1164)
    promiseReactionJob

Screenshot 2022-04-18 at 15 38 47 Screenshot 2022-04-18 at 15 41 10

Acariah commented 1 year ago

+1 As I can confirm this is still an issue.

My workaround was manually generating the markup for cart-notification when the key selector returns null from the key mismatch

MathiasWDN commented 1 year ago

+1 As I can confirm this is still an issue.

My workaround was manually generating the markup for cart-notification when the key selector returns null from the key mismatch

Fingers crossed that they'll look into it in 2024 🤞

shestakov-vladyslav commented 1 year ago

I have the same problem

shestakov-vladyslav commented 1 year ago

I have the same problem

MarkRijkelijkhuizen commented 9 months ago

This also results in the product_added_to_cart event from webpixel tracking returning empty

analytics.subscribe("product_added_to_cart", async (event) => {
  dataLayer.push(CODE_HELPER.getAddToCartData(event));
});

const CODE_HELPER = {
  getAddToCartData(evt) {
    return {
      event: "add_to_cart",
      currency: evt.data.cartLine.merchandise.price.currencyCode,
      value: evt.data.cartLine.merchandise.price.amount,
      items: [
        {
          item_id: evt.data.cartLine.merchandise.id,
          item_name: evt.data.cartLine.merchandise.product.title,
        },
      ],
    };
  }
}