Implementing AJAX Cart Functionality in Shopify Without Page Refresh

I’m working on a Shopify store and trying to implement an add to cart feature that doesn’t refresh the page. Currently when someone clicks add to cart, it redirects to the cart page which creates a poor user experience.

I found Shopify’s AJAX API documentation but I’m struggling with the implementation. They provide a JavaScript library with functions like:

// Function to add items to cart via AJAX
StoreAPI.insertProduct = function(product_id, qty, callback) {
  var qty = qty || 1;
  var options = {
    method: 'POST',
    endpoint: '/cart/add.js',
    payload: 'quantity=' + qty + '&id=' + product_id,
    format: 'json',
    onSuccess: function(item_data) { 
      if ((typeof callback) === 'function') {
        callback(item_data);
      }
      else {
        StoreAPI.onProductAdded(item_data);
      }
    },
    onFailure: function(request, status) {
      StoreAPI.handleError(request, status);
    }
  };
  jQuery.ajax(options);
};

And also:

// Function to add items from form data
StoreAPI.insertFromForm = function(form_element, callback) {
    var options = {
      method: 'POST',
      endpoint: '/cart/add.js',
      payload: jQuery('#' + form_element).serialize(),
      format: 'json',
      onSuccess: function(item_data) { 
        if ((typeof callback) === 'function') {
          callback(item_data);
        }
        else {
          StoreAPI.onProductAdded(item_data);
        }
      },
      onFailure: function(request, status) {
        StoreAPI.handleError(request, status);
      }
    };
    jQuery.ajax(options);
};

I tried setting up my form like this:

<form action="/cart/add" method="post" class="product-form" id="item-form-{{ product.id }}">
    <input type="submit" name="add" value="Add to Cart" class="btn-primary" onclick="return false; StoreAPI.insertProduct({{variant.id}}, 1, 'success')"/>
</form>

But nothing happens when I click the button. I also tried using the form-based approach but keep getting variant ID errors. What’s the correct way to implement this? I’ve been stuck on this for days and would really appreciate some guidance on getting AJAX cart functionality working properly.

you’re missing dataType and contentType in your ajax call. shopify’s cart api is picky about headers. add dataType: 'json' and contentType: 'application/x-www-form-urlencoded; charset=UTF-8' to your options. also, that ‘success’ callback should be a function, not a string.

Your button setup is causing the problem. You’re mixing onclick with form submission, which creates conflicts. The onclick="return false;" stops the form from submitting, but your StoreAPI call isn’t structured right either.

I ran into the same thing when I first built AJAX cart functionality. What fixed it for me was separating everything completely. Skip the form submit button and use a regular button with a click handler instead.

Here’s what works:

<button type="button" class="btn-primary add-to-cart" data-variant-id="{{variant.id}}">Add to Cart</button>

Then handle the click separately:

$('.add-to-cart').on('click', function(e) {
    e.preventDefault();
    var variantId = $(this).data('variant-id');
    StoreAPI.insertProduct(variantId, 1, function(item) {
        // Handle success - update cart count, show notification, etc.
        console.log('Item added:', item);
    });
});

Also check that your StoreAPI library loads before you try using it. Those variant ID errors might be happening because the variant object isn’t available where you’re calling it. Make sure you’re on a product page where the variant variable actually exists.

your onclick syntax is the problem - you can’t mix form submission with onclick events like that. ditch the form and just use a button with proper ajax setup. also check your browser console for errors. i bet your StoreAPI isn’t loading right or has typos in the function names.

You’re trying to pass a string callback (‘success’) to StoreAPI.insertProduct, but it expects a function reference. That won’t work.

I ran into this same issue building an AJAX cart for a custom theme. Your StoreAPI looks like a custom wrapper, not Shopify’s native one. Double-check that StoreAPI.onProductAdded and StoreAPI.handleError are actually defined - if they’re not, your AJAX calls will fail silently.

Here’s what worked for me:

function addToCart(variantId) {
  StoreAPI.insertProduct(variantId, 1, function(response) {
    // Your success handling here
    alert('Product added to cart!');
  });
}

Then update your button:

<button type="button" class="btn-primary" onclick="addToCart({{variant.id}})">Add to Cart</button>

Also make sure jQuery loads before your StoreAPI script. Those variant ID errors usually mean the variant object is null or you’re testing on a page where it doesn’t exist.

Your form structure and event handling are causing the problem. I ran into this same issue last year - Shopify’s AJAX cart needs proper error handling and the right variant data structure. You can’t just pass the variant ID through the function call. It needs to be a hidden input field because that’s what the cart API expects:

<form action="/cart/add" method="post" class="product-form" id="item-form-{{ product.id }}">
    <input type="hidden" name="id" value="{{ variant.id }}">
    <input type="hidden" name="quantity" value="1">
    <button type="submit" class="btn-primary">Add to Cart</button>
</form>

Then intercept the form submission:

$('.product-form').on('submit', function(e) {
    e.preventDefault();
    StoreAPI.insertFromForm($(this).attr('id'));
});

Those variant ID errors happen when the variant object is undefined or you’re testing outside a product context. Always check that the variant exists before rendering the form.