If you’re not familiar with what AJAX is – in simple terms it is a method of performing a job/task without the need of a page reload. Think of the cart/checkout totals updating when you change the shipping method.

WooCommerce already makes use a of a AJAX add to cart button on the archive page, but when it comes down to the product page it will by default always refresh the entire page. For a more streamlined user experience it would be interesting to have this add to cart button also work with AJAX.

As a bonus, adding products to the cart through this method is also a bit lighter on the server as it doesn’t require to load the entire page, but instead only a small part of it.

In this post I’ll show how you can change the add to cart button to use AJAX using a code snippet. 

Making the Add to Cart Button Use AJAX

To accomplish our goal we can use a few code snippets, without the need of changing the data or overriding the add to cart template(s).

Use AJAX for the Add to Cart Button

The first thing to do is change the behaviour of the ‘Add to Cart’ button itself. This is done through the following code snippet which will ensure the button doesn’t cause a page-reload and it will send the data over to the server through a AJAX call.

Having this installed as-is won’t do much, it will send the data to the server and show a loading block over the Add to cart button.

Handling the AJAX Add to Cart Request

To handle the request we’re going to add the following code snippet which heavily utilizes existing WooCommerce functionality to handle the adding to the cart based on the available data.

This will also ensure the server sends back data to update the mini-cart for example. Lastly this removes the default Add to cart handler as this would cause additional add-to-cart of the product.

Add Notices to Fragments

The third and last part is not specifically required, but definitely recommended. This code ensures that any notices are also returned by the server and shown to the customer. If the product was successfully added (or something failed) it will show the notice accordingly to the result.

Also worth noting that by not using this code snippet it would show the ‘Product X added to the cart’ notice on the next page reload.

Do note that the first code snippet inserts the messages at a fixed location. It could be your theme uses a different location to display notices, if that is the case you may want to change things in that code snippet accordingly.

AJAX Add to Cart VS Default Button Result

I think the end result is very smooth and definitely worth adding to your website.

Before:

After:

About the author: Jeroen Sormani is actively building WordPress, WooCommerce and Easy Digital Downloads plugins. Slightly obsessed by writing high quality code.
Follow Jeroen on Twitter

42 comments

  1. Been trying to figure this out for ages! I’ve got a custome ‘Quote Builder’ embedded into the homepage of my site. People would look through a 200 page pdf, add product code and everything to the build, add it, and it would refresh and go back to page 1 of the PDF. This has just saved the day for me, thank you so much!

  2. This post has been so helpful, thank you!

    I do have one follow-up question. Can you please explain what part of the code inserts the notice fragments into the fixed location of the theme?

    Add-to-Cart currently scrolls to the top of the page. I’m trying to scroll down to a cart section I added using a shortcode ([woocommerce_cart]).

  3. Hi there and thanks for a great blogpost. This solution is much more cleaner then “pro” plugin solutions out there, and works elegant in all my WooCommerce installs. The added notice handler is also working as a charm with complex ajax onload situations.

    It would be great if you have a “similar clean way” to add a number (default) quantity field into the mini cart, in harmony with this blog post functions.

    Keep sharing!
    / Jonas Lundman

  4. That’s what I was looking for, great job!
    To make it work, I had to change ‘messages’ with ‘notices’ on line 14 of the third snippet. For the rest, it works like a charm.

    I just have a question: is there any chance to make it work also on archive pages? I tried, but $all_notices are always empty.. do you happen to know why?

  5. After testing and debugging lots of codes, try this one and it’s working FANTASTIC.
    Thanks Jeroen Sormani, this was life saving!

  6. This post is really helpful.

    after a long search and tired with every option finally with this script i am able to implement ajax call on the single product page.

  7. Thanks for this! It all works perfectly, except for the last bit, for me. The “Add Notices to Fragments” code. With the code, it doesn’t show the notice that an item has been successfully added. When I remove that part of the code, and I add an item to the cart, then refresh the page, the notice shows. Any reason why it doesn’t work as intended?

    1. Hi,

      There was a outdated parameter, the ‘messages’ needed to be updated to ‘notices’. The current code on the page is updated and works 👍

  8. This code does not work in wordpress 5.6 with new jquery library when add to cart clicked in variable products, please help me to solve it. Thanks

  9. This snippet is not working from WC 4.8 It was working earlier pretty fine. Do you think you can update the code in a manner so that everything works properly without any issue. I think add-to-cart is not getting data for variable or grouped product as they have variations available. So we need to provide variation id’s for them any thoughts?

    1. Hi,

      Thanks, I’ve just reviewed this post and updated the snippets to work and properly make the ajax add to cart work on product pages with the latest versions (tested with simple/variable products, not grouped though).

      Cheers,
      Jeroen

  10. Hi,

    Great code.
    I have a custom success.php notice in my child theme. I also load global $post in there to get the product image and a shortcode as well . This gives errors. Probably because only html is loaded or something. Any ideas?

    1. Hi,

      Loading a global variable can be done in a template generally, its not limited to HTML only if its a .php file. Its give details without knowing the setup/error.

      Cheers,
      Jeroen

  11. Hi, I have another questions, solved the question above, but it looks like the quantity does not work. If I set the quantity to 10 for example, it just adds 1 product to the cart,

      1. Thanks, the form.context replacement works as a charm with both quantaties, variable products and addons like bookings and more.

  12. I really can’t thank you enough for creating this snippet. Works like an absolute dream :) I’m using an Elementor based site just in case others are looking for a way to add AJAX to the Elementor Add To Cart on the product page.

  13. Hi Jeroen,

    Thanks for the tutorial!

    Do you know how to make it so that only errors are shown as a notice?

    1. Hi Cris,

      Although I haven’t tested it myself, I think you can remove the other notice types from line #8 in the last snippet.

      Cheers,
      Jeroen

  14. When I place the code through the function.php file, and then click the button, I get a light white box over the button and a spinning wheel on my pointer. Nothing gets added to the cart and the spinning wheel doesn’t go away. If I refresh the page it does add the product to the cart, but it isn’t processing the action without refreshing. Any ideas?

    1. Hi Gary,

      Sounds like there’s an error happening in either the JS console or to be found in the PHP error log. This would be needed in order to determine what is the cause of this and how to resolve.

      Cheers,
      Jeroen

  15. Perfect tutorial, thanks very much. One question though; I already have a piece of code that shows the mini-cart after adding something to the cart, so I don’t need the notifications. But when I leave out the last snippet the notice still appears on the cart page which makes sense, but can I remove that also without the notifications appearing on the product page?

    1. Hi Victor,

      If you keep the last snippet and remove most of the contents of the function and keep the ‘wc_clear_notices();’ it should work ;-)

      Cheers,
      Jeroen

  16. Hi,
    thank you so much for sharing this code. Very helpful for those who don’t want to use an extra plugin.
    But I’ve got this issue on my product page: Ajax button works perfectly but there’s no way to show default Woocommerce message above (“Added to cart etc…) when you click on the button and add product(s) to the cart. Maybe I’ve got something wrong with that…
    Anybody having the same behaviour?

    1. Hi Christian,

      Does it show the notice on the next page load for you?
      The last snippet in the post should take care of adding the notice and ensuring it doesn’t show on a future page load (which can be confusing to the customer).

      Cheers,
      Jeroen

  17. Hi,

    Is it possible to add an AJAX add to cart button/s to a search page? I have a site where customers often search for products and then add them to the cart directly from the search results. However, when they add an item from search into their cart they are redirected to the homepage instead of remaining on the search results.

    Thanks!

    1. Hi Tom,

      Sure, its possible to modify the search results to include have AJAX add to cart buttons.

      Unfortunately I don’t have something readily available for this. Feel free to reach out through the contact form if you need help with creating this.

      Cheers,
      Jeroen

  18. Very handy snippet to have! Clean code and simple to use, works with WC 6! Thank you for sharing the knowledge.

  19. Thanks! Small edit for variable products:

    if(form.find(‘[name=variation_id]’).length) {
    formData.append(‘add-to-cart’, form.find(‘[name=variation_id]’).val() );
    } else {
    formData.append(‘add-to-cart’, form.find(‘[name=add-to-cart]’).val() );
    }

  20. Hi Jeroen,

    Thank you for the tutorial. I adapted it to my needs and I’m happy with it.
    However, I accidentally noticed that this action

    remove_action( ‘wp_loaded’, array( ‘WC_Form_Handler’, ‘add_to_cart_action’ ), 20 );

    works great on single products page but then will not allow to fire an url with

    ?add-to-cart=id on any other page…

    I have tried to place it in an if statement and no luck.
    You probably have an idea on how to solve this!
    Thank you

    1. Hi Max,

      Maybe you can make the other links the same (HTML) structure as the original buttons?
      Would be the easiest solution. I don’t have anything readily for conditionally removing the action, but you could check if the page is a product page or a archive page specifically.

      Cheers,
      Jeroen

  21. Hi,

    I face a problem. It added double products on cart. Suppose when i add quantity 1 it adds 2. for 2 it adds 4. Can yopu help about it?

  22. Great code snippet! Thank you for sharing this.

    And I might be a bit late to the party so to speak. But in our form.cart there is also a “Buy Bow” button which is pretty common. This button normally adds the product to the cart and redirects the user to the checkout. However, the normal behaviour of the Buy Now function is overwritten by the Ajax Code and no longer works. Do you know a good workaround for this?

    1. Hi Gustav,

      Unfortunately haven’t used/tested ‘Buy now’ buttons, so I don’t have a workaround readily available..

      Cheers,
      Jeroen

Leave a Reply

Your email address will not be published. Required fields are marked *