tetchi blog

Tetchi's blog about life and stuff

Shopify Tutorial: Creating a Threadless-like Add-to-Cart button using jQuery and AJAX

In this tutorial we will be modifying the product page of the Ripen theme to work more like the product page on Threadless. We’re going to be modifying the Ripen theme, but this tutorial is applicable to any Shopify theme. I would like to thank John Tajima again for teaching me how AJAX and JSON objects work with Shopify. We will also make it so that the number of products in the cart displayed automatically updates after you add an item to the cart.

A quick demo of the completed theme in action

1. Install jQuery

If you are unsure of how to do this, please see Steps 1 to 3 from this tutorial.

2. Install Colorbox

Grab the jQuery plugin Colorbox here, and upload it to your theme assets. We’re going to be using Colorbox to get the lightbox popup when a product is added to the cart. I usually use Fancybox for lightboxes, but I decided to go with Colorbox for this tutorial because it “can be called directly, without assignment to an element”. This means that I can call a Colorbox method, and create a lightbox on-the-fly when the “Add to Cart” button is clicked, but with Fancybox this would be impossible.


In your theme assets, you should have “jquery.colorbox-min.js” and “colorbox.css”.

Be sure to add these two files in the <head> section to your theme.liquid as well.

 ...other assets {{ 'colorbox.css' | asset_url | stylesheet_tag }} {{ 'jquery.colorbox-min.js' | asset_url | script_tag }} 

3. Modify the “Add to Cart” button

Open your product.liquid file, and locate the input button for adding to the cart. The input button looks like this:


We want to do two things to this button: first, we want to make it so that even if the user clicks on it, the user is not taken to the cart page. Second, we want to call a custom function (that we’re going to be writing shortly) that makes an AJAX call to add the product to the cart.

 onclick="return false; addItem('add-to-cart');"/> 

The addItem function takes the form’s id as a parameter. This is so that when we use jQuery later, we know which form to select. The opening tag for your form should look like this:

4. Preparing product.liquid

Add the following line at the top of product.liquid.


The added-box is where the content of the lightbox will be inserted. We need to wrap it in another div with a “display:none;” so that the content of the lightbox are not displayed on the actual page.

5. Preparing theme.liquid

Next, we have to modify theme.liquid a little so that the number displayed for the number of items in the cart updates automagically. In theme.liquid, find a place where you want to show a link to the cart. In this tutorial, I’m going to put it in the right column, under where it says “Shopping Cart”.

{% if cart.item_count == 0 %} Your cart is empty. {% endif %}

What’s important here is that the <a> tag has the id “cart-number”, so that we can select it with jQuery later to modify its contents.

6. Displaying the number of items in the cart when the product page is loaded

In theme.liquid, locate the <head> section. This is where we will be adding the Javascript to make it all happen.

First, we need to add create a variable called cartCount, which will store the number of items that are in the cart. When the product page is loaded, we want to query the number of items that are currently in the cart with Liquid, and then store it in a Javascript variable called ‘cartCount’.

Next, we want to create a function that is called upon when the page is done loading. When the page is loaded, the link with the id “cart-number” that we created in the last step should display the right number of items in the cart. We can do this by adding the the following function in the script:

7. Make the AJAX call to add the product to the cart

Let’s now create the function for adding the product to the cart. Below the document.ready function, add the following function.

The addItem function makes an AJAX request using jQuery.ajax().

  • the type option specifies what kind of request we’re going to make. We will be making a POST request.
  • the url option tells the server to add the product to the cart.
  • the dataType option specifies the type of data that we want back from the server. We want to receive the data as JSON objects.
  • the data options specifies what data we want to send to the server. We’re going to be selecting the form from the product page, and using the serialize() method on it to make it into a string that is readable by the server.
  • If the AJAX call is successful, the addToCartOk function is called. If it is not, the addToCartFail function is called.

8. addToCartOk – the function for a successful AJAX call

Let’s start off by creating the function that is called when the product is added to the cart successfully.

 ... data: $('#'+form_id).serialize(), success: addToCartOk, error: addToCartFail }); } function addToCartOk(product) { cartCount++; $('#added-box').html(product.title + ' was added to the cart!'); $('#cart-number').replaceWith("View cart (" + cartCount + ")"); $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } 

Now, the lightbox that I created isn’t the prettiest thing in the world, but you can customize the look and feel by adjusting Colorbox’s properties. You can also modify colorbox.css.

To change the color of the overlay, open colorbox.css, and look for the #cboxOverlay selector and change the background to the color or image of your choice. To make my overlay black, I set #cboxoverlay to the following:


9. addToCartFail – the function for an unsuccessful AJAX call

The last thing we want to do is to create a function that is called if the product was not able to be added to the cart. The primary reason for not being able to add something to the cart is that there is not enough inventory for that item.

 ... $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } function addToCartFail(obj, status) { $('#added-box').html('The product you are trying to add is out of stock.'); $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } 

Alternatively, you can use the code below to receive the actual message of the error. This was my initial approach, but I found that sometimes the Shopify servers won’t return the proper response, which in turn would not make the lightbox appear at all. If anybody could give me some insight on why this happens, that would be awesome.

 ... $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } function addToCartFail(obj, status) { try { var response = jQuery.parseJSON(obj.responseText); $('#added-box').html(response.description); } catch(e) { $('#added-box').html("There was an error"); } $.fn.colorbox({ open:true, width: "400px", innerHeight: "80px", inline:true, href:"#added-box", transition: 'none' }); } 

10. Conclusion

You now have a product page that works similar to that of Threadless. I’m not too happy with the way the addToCartFail function is working right now, but for now it seems like it’s the only way to have the lightbox appear every time there is an error. You can download the completed theme here.

Big thanks again to John Tajima for his help!


  • Keith
    Keith on January 23rd, 2011

    does not work on Onyx theme.

  • darbotron
    darbotron on February 1st, 2011

    Hey dude,

    Nice work :)

    I’ve done this same thing in mootools 1.3 (not the version that’s on the global asset area at shopify) if you’re interested in seeing the code just let me know.

    It makes no difference really, but I just prefer the way mootools code looks ;)


  • Andrew
    Andrew on April 26th, 2011

    I’m having trouble getting this to work. Is there anything assumed you didn’t mention. Other scripts etc.. I’m using my own theme with this. Thanks

  • Tetsuro
    Tetsuro on April 28th, 2011

    Hey Andrew,

    Hmm… I don’t think I’ve left anything out. What’s your store’s URL? Maybe I can take a look and help out.



  • Jamie
    Jamie on May 25th, 2011

    Hi Tets,

    I can’t figure out what I have done. I can’t seem to click add to cart at all now. Does it work with slate theme?

    I am not too familiar with js but your tut looked pretty straightforward so I gave it a go. Can you take a look at my shop for me? Password is unibox11 for the storefront. Need to get it sorted pretty soon as my launch is Tuesday.


  • Rick
    Rick on November 8th, 2011

    I couldn’t get this to work either… I’m using a heavily customized helvetica theme… I’d really like to be able to use this but just no dice…

    I’m not sure but would it be anything to do with the use of the javascript statement ‘return false;’ in the onclick button? It looks like that may be stopping the calling of the addItem function?

    Any ideas Tets?


  • Jo
    Jo on December 13th, 2011

    Hey all, just following through the tutorial and yes, pretty sure there’s been a couple of stages missed.
    The AddToCart function isn’t defined anywhere?

  • Jo
    Jo on December 13th, 2011
  • tetchi
    tetchi on December 21st, 2011

    Gah! Sorry for that Jo, it looks like I messed up the pagination in WordPress. Taking a look now….

    UPDATE: I’ve fixed the pagination issue. Thanks for catching that!

  • Siegfried
    Siegfried on July 3rd, 2013


    I am not sure what I am doing wrong but I keep getting a “Failed to load resource: the server responded with a status of 400 (Bad Request) “.

    Any advice?

  • Owen Sechrist
    Owen Sechrist on July 9th, 2013

    Just curious…. is step one linking to another tutorial the correct link? Doesn’t seem relevant to making sure jQuery is installed.

    I wasn’t able to get this working yet, will try again later. I tried a method from a different tutorial and also got a status 400 error.

  • tetchi
    tetchi on July 10th, 2013

    @Owen ah, I wrote this tutorial 3 years ago and I’ve since updated the “Terms and Conditions” one to auto-include jQuery. When I get a chance I’ll do the same with this one.

  • Alicia Leo
    Alicia Leo on July 23rd, 2013

    I can’t get this to work, but it’s exactly what I need! Any ideas?

  • H
    H on August 9th, 2013

    Also bummed that this doesn’t work anymore. This is the only tutorial I found which shows shopify users how to do something like this, which is stranger because it’s a pretty common functionality.

  • tetchi
    tetchi on August 9th, 2013

    @H Thanks for the feedback. Looks like there aren’t too many other resources out there for this.

    As soon as I’m finished with the Shopify Theme from Scratch series, I’ll do a re-write of this article with better examples.

Post a comment