> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Cart API

> Manage shopping cart items in the browser

The Cart API manages shopping cart state in the browser's localStorage. Cart data persists across page refreshes and browser sessions.

<Warning>
  Cart data is stored in the browser's `localStorage`. If the user clears browser storage, the cart will be lost.
</Warning>

## getCart

Returns all items currently in the cart.

```javascript theme={"system"}
const cartItems = shoppex.getCart();

cartItems.forEach(item => {
  console.log(item.product_id, item.quantity);
});
```

### Response

<ResponseField name="return" type="CartItem[]">
  <Expandable title="CartItem object">
    <ResponseField name="product_id" type="string">
      Product unique identifier
    </ResponseField>

    <ResponseField name="variant_id" type="string">
      Selected variant ID (empty string if no variant)
    </ResponseField>

    <ResponseField name="quantity" type="number">
      Item quantity
    </ResponseField>

    <ResponseField name="addons" type="CartAddon[]">
      Selected add-ons
    </ResponseField>

    <ResponseField name="custom_fields" type="Record<string, string>">
      Custom field values
    </ResponseField>

    <ResponseField name="price_variant_id" type="string">
      Selected price variant ID
    </ResponseField>
  </Expandable>
</ResponseField>

## getCartItemCount

Returns the total number of items in the cart.

```javascript theme={"system"}
const count = shoppex.getCartItemCount();
document.getElementById('cart-badge').textContent = count;
```

## addToCart

Adds an item to the cart or increments quantity if it already exists.

```javascript theme={"system"}
// Basic usage
shoppex.addToCart('prod_abc123', 'var_001', 1);

// With options
shoppex.addToCart('prod_abc123', 'var_001', 2, {
  addons: [{ id: 'addon_1', quantity: 1 }],
  custom_fields: { 'License Name': 'John Doe' },
  price_variant_id: 'pv_pro'
});
```

### Parameters

<ParamField path="productId" type="string" required>
  Product unique identifier
</ParamField>

<ParamField path="variantId" type="string" required>
  Variant ID. Use empty string `''` for products without variants.
</ParamField>

<ParamField path="quantity" type="number" default="1">
  Number of items to add
</ParamField>

<ParamField path="options" type="CartAddOptions">
  <Expandable title="CartAddOptions">
    <ParamField path="addons" type="CartAddon[]">
      Add-ons to include
    </ParamField>

    <ParamField path="custom_fields" type="Record<string, string>">
      Custom field values
    </ParamField>

    <ParamField path="price_variant_id" type="string">
      Selected price variant
    </ParamField>
  </Expandable>
</ParamField>

### Example: Add to Cart Button

```javascript theme={"system"}
function handleAddToCart(productId, variantId) {
  const quantity = parseInt(document.getElementById('quantity').value) || 1;

  // Collect selected addons
  const addons = [];
  document.querySelectorAll('.addon-checkbox:checked').forEach(cb => {
    addons.push({ id: cb.value, quantity: 1 });
  });

  shoppex.addToCart(productId, variantId, quantity, { addons });

  // Update UI
  updateCartBadge();
  showNotification('Added to cart!');
}
```

## updateCartItem

Updates an existing cart item.

```javascript theme={"system"}
shoppex.updateCartItem('prod_abc123', 'var_001', {
  quantity: 5,
  addons: [{ id: 'addon_2', quantity: 1 }]
});
```

### Parameters

<ParamField path="productId" type="string" required>
  Product unique identifier
</ParamField>

<ParamField path="variantId" type="string" required>
  Variant ID
</ParamField>

<ParamField path="updates" type="object" required>
  <Expandable title="Update fields">
    <ParamField path="quantity" type="number">
      New quantity
    </ParamField>

    <ParamField path="addons" type="CartAddon[]">
      Updated add-ons
    </ParamField>

    <ParamField path="custom_fields" type="Record<string, string>">
      Updated custom fields
    </ParamField>
  </Expandable>
</ParamField>

## removeFromCart

Removes an item from the cart.

```javascript theme={"system"}
shoppex.removeFromCart('prod_abc123', 'var_001');
```

### Parameters

<ParamField path="productId" type="string" required>
  Product unique identifier
</ParamField>

<ParamField path="variantId" type="string" required>
  Variant ID
</ParamField>

## clearCart

Removes all items from the cart.

```javascript theme={"system"}
shoppex.clearCart();
```

## Cart Backup

The SDK can backup the cart before checkout to restore it if checkout is cancelled.

### createCartBackup

```javascript theme={"system"}
// Called automatically before checkout
shoppex.createCartBackup();
```

### restoreCartFromBackup

```javascript theme={"system"}
// Restore cart after cancelled checkout
const restored = shoppex.restoreCartFromBackup();

if (restored) {
  console.log('Cart restored');
} else {
  console.log('No backup available');
}
```

## Complete Cart UI Example

```html theme={"system"}
<div id="cart">
  <h2>Shopping Cart</h2>
  <div id="cart-items"></div>
  <div id="cart-total"></div>
  <button onclick="goToCheckout()">Checkout</button>
</div>

<script>
async function renderCart() {
  const items = shoppex.getCart();
  const container = document.getElementById('cart-items');

  if (items.length === 0) {
    container.innerHTML = '<p>Your cart is empty</p>';
    return;
  }

  // Fetch product details for display
  const { data: products } = await shoppex.getProducts();
  const productMap = new Map(products.map(p => [p.uniqid, p]));

  let total = 0;

  container.innerHTML = items.map(item => {
    const product = productMap.get(item.product_id);
    if (!product) return '';

    const itemTotal = product.price * item.quantity;
    total += itemTotal;

    return `
      <div class="cart-item">
        <img src="${product.images[0]?.url}" alt="${product.title}" style="border-radius: 8px;">
        <div class="item-info">
          <h4>${product.title}</h4>
          <p>${shoppex.formatPrice(product.price, product.currency)}</p>
        </div>
        <div class="quantity">
          <button onclick="updateQuantity('${item.product_id}', '${item.variant_id}', ${item.quantity - 1})">-</button>
          <span>${item.quantity}</span>
          <button onclick="updateQuantity('${item.product_id}', '${item.variant_id}', ${item.quantity + 1})">+</button>
        </div>
        <button onclick="removeItem('${item.product_id}', '${item.variant_id}')" class="remove">Remove</button>
      </div>
    `;
  }).join('');

  document.getElementById('cart-total').innerHTML = `
    <strong>Total: ${shoppex.formatPrice(total, products[0]?.currency || 'USD')}</strong>
  `;
}

function updateQuantity(productId, variantId, newQuantity) {
  if (newQuantity < 1) {
    shoppex.removeFromCart(productId, variantId);
  } else {
    shoppex.updateCartItem(productId, variantId, { quantity: newQuantity });
  }
  renderCart();
}

function removeItem(productId, variantId) {
  shoppex.removeFromCart(productId, variantId);
  renderCart();
}

renderCart();
</script>
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Checkout API" icon="credit-card" href="/sdk/api/checkout">
    Redirect customers to secure hosted checkout
  </Card>

  <Card title="Products API" icon="box" href="/sdk/api/products">
    Fetch products, variants, and categories
  </Card>
</CardGroup>
