# cart (https://docs.salla.dev/twilight/react/api/modules/cart)



Use `cart` to read a cart. It only reads: adding, changing and removing items goes through the SDK (`Salla.cart.addItem(id)` and friends, see [Salla SDK and events](https://docs.salla.dev/twilight/react/guide/salla-sdk-and-events)).

The cart id comes from the SDK in the browser, so `cart.queries.currentId()` reads it first and the detail query runs once it has one:

```tsx title="app/components/cart/CartPage.tsx"
import { useQuery } from '@tanstack/react-query';
import { cart } from '@salla.sa/twilight-theme-engine/api/cart';

export function CartPage() {
  const { data: cartId } = useQuery(cart.queries.currentId());

  const { data: cartData } = useQuery({
    ...cart.queries.detail(cartId!),
    enabled: !!cartId,
  });

  return <p>{cartData ? `${cartData.items.length} items` : 'Your cart is empty'}</p>;
}
```

## Methods [#methods]

| Method         | Parameters       | Returns                   | Request                  | Login needed                         |
| -------------- | ---------------- | ------------------------- | ------------------------ | ------------------------------------ |
| `get`          | `cartId: number` | `Promise<Cart \| null>`   | `GET cart/{cartId}`      | No (the cart id identifies the cart) |
| `getOrThrow`   | `cartId: number` | `Promise<Cart \| null>`   | Same as `get`            | No                                   |
| `getCurrentId` | none             | `Promise<number \| null>` | Asks the SDK, no request | No                                   |

`get` returns the `cart` object with `loyalty` and `gift` set from the response (`null` when absent). It returns `null` for the whole cart once the cart has become an order. `getOrThrow` turns a 404 or 410 into a not-found page and rethrows other errors. `getCurrentId` returns `null` on the server.

## Queries [#queries]

| Query                         | Key                      |
| ----------------------------- | ------------------------ |
| `cart.queries.detail(cartId)` | `['cart', cartId]`       |
| `cart.queries.currentId()`    | `['cart', 'current-id']` |

Both queries use `staleTime: 0` and `gcTime: 0`, because the SDK can change the cart from any page: a cached copy is never reused after the component unmounts. The keys include neither the locale nor the active scope.

## Gotchas [#gotchas]

* After an SDK change (add, remove, update), refresh the cart that is on screen:
  `queryClient.invalidateQueries({ queryKey: cart.queries.detail(cartId).queryKey })`.
* `cartId` is a number. Do not run the detail query until you have one (`enabled: !!cartId`).
* `get` does not catch errors: an expired or unknown cart rejects with `HTTPError`.
* The id is known only in the browser, so the cart is not prefetched on the server unless your own loader has the id and calls `queryClient.fetchQuery(cart.queries.detail(id))`.

## See also [#see-also]

* [Cart route](https://docs.salla.dev/twilight/react/routes/cart)
* [Authentication and scope](https://docs.salla.dev/twilight/react/api/authentication-and-scope)
* [Loading data](https://docs.salla.dev/twilight/react/guide/loading-data)
