> For the complete documentation index, see [llms.txt](https://jho406.gitbook.io/breezy/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jho406.gitbook.io/breezy/docs/recipes/shopping-cart.md).

# Shopping cart

In this recipe, we'll look at how to build a global shopping cart state. One that can be used in a header for a count of all quantity, a shopping cart panel, optimistic updates, etc. Here's how to achieve that:

Render the cart in your props [across all pages](/breezy/docs/cross-cutting-concerns.md#layouts) in your `application.json.props` and mark it as a fragment.

```ruby
json.data do
  json.cart partial: ['cart', fragment: true] do
  end

  yield
end
```

Add a slice

```javascript
import { createSlice, createAction } from '@reduxjs/toolkit'
import { updateFragments } from '@thoughtbot/superglue'

export const cartSlice = createSlice({
  name: 'cart',
  initialState: {},
  reducers: {
    addToCart: (state, action) => {
      ....logic to add something to the cart ...
    }
  },
  extraReducers: (builder) => {
    builder.addCase(updateFragments, (state, action) => {
     // Update the slice with the latest and greatest.
      return action.value
    })
  }
})
```

With `fragment` enabled, the above will populate the slice whenever a page is received, while allowing you the flexibility to make local edits using the custom `addToCart` reducer.

You can use this cart slice as you normally would with Redux selectors

```
  // For the cart component
  const cart = useSelector(state => state.cart)

  // For a header quantity component
  const cartCount = cart.lineItems.reduce((memo, line) => memo + line.qty, 0)
```

For updates to the backend, add a ujs attribute to a normal form.

```javascript
  <form action='/add_to_cart?props_at=data.header.cart' method='POST' data-sg-remote={true}>
```

```ruby
def create
  ... add to cart logic here...

  # This helper will retain the `props_at` param when redirecting, which allows the
  # partial rendering of the `show` page.
  redirect_back_with_props_at fallback_url: '/'
end
```

The above will `POST`, and get redirected back to the original page while fetching only the cart to update. This will be picked up by `extraReducers` and update the entire cart state.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jho406.gitbook.io/breezy/docs/recipes/shopping-cart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
