Experiments >

Supacart: adding a cart

Experiment #1087th April, 2021by Joshua Nussbaum

Let’s look at adding a local cart to supacart project. Since it running locally, I’m using a similar approach to what I tried in the headless cart experiment.

Cart store

The cart store will persist to localStorage. So I’m going to use my trusty svelte-local-storage-store package:

yarn add -D svelte-local-storage-store

The cart component is a store that looks like this:

import { derived } from 'svelte/store'
import { writable } from 'svelte-local-storage-store'

// cart is a store with the format `{sku: quantity}`
export const cart = writable('cart', {})

// the total number of items in the cart is derived
// by summing all the quantities in the cart store
export const count = derived(cart, $cart => {
  return Object
    .reduce((acc, sku) => acc + $cart[sku], 0)

// adds an items to the cart
export function add(sku) {
  cart.update($cart => {
    // check if the item already exsits
    if ($cart[sku]) {
      // it exists, so increment quantity
    } else {
      // it doesn't exists, so define a new record
      $cart[sku] = 1

    return $cart

// removes an item from the cart
export function remove(sku) {
  cart.update($cart => {
    // delete the sku
    delete $cart[sku]

    return $cart

// clears the cart
export function clear() {
  // set cart to an empty dictionary

Adding to the cart

Dead simple to do with just a <button> and an on:click handler:

<button on:click={() => add(product.sku)}>Add to cart</button>

Cart icon

In the upper right corner, the site displays a cart icon with the count of items:

<!-- src/routes/$layout.svelte -->

And the <CartIcon> component is defined as:

<!-- src/lib/components/CartItem.svelte --->
  // get the count store
  import {count} from '$lib/cart'

<!-- link to /cart page -->
<a class:empty={$count == 0} href="/cart">
  <span class="count">{$count}</span>
  <svg xmlns="http://www.w3.org/2000/svg" height=30 fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />

Cart page

The cart page displays a list of items in the cart:

<!-- src/routes/cart.svelte -->
  import { cart, count, remove, clear } from '$lib/cart'


{#if $count == 0}
  <p>There are no items in your cart</p>
  <a href="/">Start shopping</a>
      {#each Object.entries($cart) as [sku, quantity]}
          <td><button on:click={() => remove(sku)}>x</button></td>

  <button on:click={clear}>clear</button>
view all experiments

Stay tuned in

Learn how to add more experimentation to your workflow