Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 21

Building Your Cart Template

Recommended resources

Hello and welcome back!

In our last lesson, we built a collection page, allowing customers to browse the products in your store. We focused on creating a product grid and adding sorting functionality. Now that customers can find and select products, we need to build the next logical step in their journey: the shopping cart.

This lesson is dedicated to implementing a cart template to display line items, quantities, and totals. This is where customers review their selections before committing to a purchase, making it a critical part of the user experience. Your full-stack background will be useful here, as we'll be working with data objects and forms, but through Shopify's specific Liquid templating engine.

Our goal is to create a functional cart page similar to this:

Shopify Shopping Cart Page Example
A typical cart page, showing selected items, quantities, totals, and a checkout button. This is what we will build today.

1. The Cart Template and the Global cart Object

Just as a specific product page is rendered by templates/product.liquid, the shopping cart page, accessible at your-store.com/cart, is rendered by templates/cart.liquid (or templates/cart.json in modern themes).

The most important tool for this template is the global cart object. This Liquid object is available on every page of your theme, but its primary purpose is to provide all the necessary information to build the cart page. It contains everything from the list of items to the total price.

cart

First, let's look at the official Shopify documentation to understand the purpose of the cart template and the central role of the cart object.

Read the introduction, 'Location', and 'Content' sections. This will confirm where the template file lives and formally introduce you to the cart object, which is the cornerstone of this lesson.


2. Building the Cart's Structure

To build a functional cart, we need two main things:

  1. A form that can submit information to Shopify's backend.
  2. A loop to display each product the customer has added.

The Cart Form

From your experience with HTML, you know that forms are used to send data to a server. In Shopify, we don't use a standard <form> tag for the cart. Instead, we use a special Liquid tag: {% form 'cart', cart %}.

This tag does two things for us:

  • It generates the correct <form> HTML with the right action and method attributes to communicate with Shopify's cart endpoint.
  • It links our form to the global cart object, which is required for it to function.

Liquid tags: form

To understand the 'why' behind this specific tag, let's consult the documentation for Liquid's form tag. This will clarify why we use this special syntax instead of a plain HTML form.

Focus on the section for the 'cart' form type. Note the syntax and the explanation that it requires the cart object as a parameter. This is a core concept for making the cart interactive.

Displaying Line Items

Inside our form, we need to display each item. The cart object has a property called items which is an array of all the line items in the cart. A line item represents a specific product variant and its quantity.

We can loop through this array using a standard Liquid for loop: {% for item in cart.items %}. Inside this loop, we have access to all the details of each line item.

Let's watch a video that puts all of this together in a practical demonstration.

Getting started with Shopify theme development (from scratch / complete guide)

This video provides an excellent, step-by-step walkthrough of building the cart.liquid template. It will guide you through creating the form, looping through items, and displaying their details.

Watch the segment from 25:39 to 33:27. This is the core of our lesson. Pay close attention to: The structure: How everything is wrapped in a {% form 'cart', cart %} block. The loop: The use of {% for item in cart.items %} to display each product. Line item properties: Accessing data like item.image, item.title, item.price, and item.quantity. Filters: Using the image_url and money filters to correctly format images and prices. Line item price vs. total price: The crucial difference between item.price (the price of one unit) and item.final_line_price (the price multiplied by the quantity).

As you saw in the video, the basic structure for displaying cart items is:

{% comment %} If the cart is empty, show a message. {% endcomment %}
{% if cart.empty? %}
  <h1>Your cart is empty</h1>
  <a href="{{ routes.all_products_collection_url }}">Continue shopping</a>
{% else %}
  <h1>Your Cart</h1>
  
  {% form 'cart', cart %}
    {% comment %} Loop through each line item in the cart. {% endcomment %}
    {% for item in cart.items %}
      <div>
        <img src="{{ item.image | image_url: width: 150 }}" alt="{{ item.image.alt | escape }}">
        
        <h2>{{ item.product.title }}</h2>
        <p>{{ item.variant.title }}</p>
        <p>Price: {{ item.price | money }}</p>
        <p>Total: {{ item.final_line_price | money }}</p>
        
        {% comment %} We'll add quantity and remove controls here. {% endcomment %}
      </div>
    {% endfor %}

    <hr>
    
    <h3>Subtotal: {{ cart.total_price | money }}</h3>
    
    {% comment %} We'll add form submission buttons here. {% endcomment %}
  {% endform %}
{% endif %}

3. Making the Cart Interactive

A static list of products isn't enough. Customers need to be able to modify their cart and proceed to checkout. This functionality is achieved with standard HTML inputs that have special name attributes Shopify recognizes.

Updating Quantities

To allow users to change the quantity of an item, we add an <input> field for each line item.

  • The input: <input type="number" name="updates[]" value="{{ item.quantity }}">
  • The trigger: <input type="submit" name="update" value="Update Cart">

When the "Update Cart" button is clicked, the form is submitted. Shopify's backend sees the name="updates[]" array and updates the quantities for each line item accordingly before reloading the page.

Removing Items

Removing an item is even simpler. The line item object (item) has a special property called url_to_remove that generates a unique URL. We just need to create a link:

  • The link: <a href="{{ item.url_to_remove }}">Remove</a>

Clicking this link will instantly remove the item and reload the cart page.

Proceeding to Checkout

Finally, the most important button. To create a checkout button, we add a submit button with name="checkout":

  • The button: <input type="submit" name="checkout" value="Checkout">

When this is clicked, Shopify takes the current state of the cart and redirects the user to the secure checkout process.

The Shopify documentation provides clear, concise examples for each of these actions.

cart

Let's refer back to the official documentation for a quick reference on implementing these interactive features. It provides the exact syntax for each one.

Review the sections 'Proceed to checkout', 'Remove line items from the cart', and 'Update line item quantities'. These short sections give you the precise code needed for each function.

Test your understanding!

A client wants to simplify the cart page. They ask you to remove the "Update Cart" button. They want the quantities to update automatically as soon as a user changes the number in the quantity input field, without reloading the page.

Based on what we've covered in this lesson, is this possible using only Liquid and the form submission methods discussed? Why or why not?

Show answer

No, this is not possible using only the methods we've covered today. The name="updates[]" mechanism for updating quantities requires a form submission to send the new data to the Shopify server, which inherently involves a page reload.

To achieve an automatic update without a page reload, you would need to use client-side JavaScript to listen for the change event on the input field and then use Shopify's Ajax API to send the update request in the background. We will cover the Ajax API in a future lesson! This is a great example of where server-side rendering with Liquid ends and client-side interactivity with JavaScript begins.


Conclusion

Congratulations! You have now built one of the most essential pages of any e-commerce site. By understanding the cart object and its associated form tags, you can create a fully functional and user-friendly cart experience.

Here are your key takeaways:

  • The templates/cart.liquid file renders the /cart page.
  • The global cart object is the single source of truth for all cart data in Liquid.
  • All cart interactions must happen within a {% form 'cart', cart %} block.
  • You loop through cart.items to display each line item. Key properties include item.product.title, item.final_line_price, and item.quantity.
  • Functionality is enabled through specific name attributes:
    • name="updates[]" for quantity inputs.
    • name="update" for the update button.
    • name="checkout" for the checkout button.
  • item.url_to_remove provides a simple link to delete an item from the cart.

In the last two lessons, you wrote HTML for a product card on the collection page and for a line item on the cart page. You may have noticed that they are very similar. Copying and pasting this code isn't ideal, as it violates the "Don't Repeat Yourself" (DRY) principle of software development.

In our next lesson, we will address this directly by learning how to create reusable UI components like product cards using snippets. This will allow us to define our product card markup once and include it anywhere we need it, making our theme more efficient and easier to maintain.