# Preview and Verify Cart Edits

> Use compact responses, dry runs, named CSS blocks and sample carts to review changes without touching a shopper cart.

Canonical URL: https://3bdc8bdc6dfd:3005/guides/cart-edit-loop

Cart edits return a small summary by default. Dry runs let you review an edit
before saving, and sample-cart URLs let you inspect reward states without
changing a shopper's cart. All rendering happens in your own browser.

These features require the updated MCP, API, renderer and island runtime.

## Read only what you need

Call `lexsis_cart` with `action: "get"` and these `args`:

```json
{
  "cart_profile_id": "PROFILE_UUID",
  "fields": ["id", "version", "design_spec", "layout_schema"]
}
```

`fields` accepts profile fields and dotted paths such as
`design_spec.shell.title`. Unknown fields are errors. Omit `fields` for compact
profile metadata; use `response: "full"` for the complete profile. Use
`include_history: true` when you need lifecycle audit entries.

`cart_edit`, `cart_create`, `cart_duplicate`, `cart_promotions_edit` and
`cart_rollback` also return summaries by default. Set `response: "full"` for
their complete profile response.

## Compile before saving

Call `lexsis_drafts` with `action: "cart_edit"`:

```json
{
  "cart_profile_id": "PROFILE_UUID",
  "expected_version": 10,
  "page_id": "PAGE_UUID",
  "dry_run": true,
  "patch": {
    "design_patch": {"shell": {"title": "Your cart"}}
  }
}
```

The result contains `version`, `dry_run`, `updated_fields`, `module_tree`,
`compile_errors`, `warnings`, and a temporary `preview_url`. The module tree
reports IDs, regions, enabled state and visibility against an empty sample
cart. If static evaluation is unavailable, conditional entries remain
`"conditional"` and `visibility_error` explains the limitation.

The draft version and history do not change. Invalid source returns
`compile_errors` and no preview URL. A stale `expected_version` still fails.
Stored settings without an effect return `setting_not_rendered` warnings;
supported title edits do not.

Open the returned URL to review it. To save, repeat the edit with
`dry_run: false` and the same expected version. Saving returns:

```json
{
  "cart_profile_id": "PROFILE_UUID",
  "version": 11,
  "updated_fields": ["design_spec"],
  "warnings": [],
  "preview_url": "SIGNED_PREVIEW_URL",
  "readiness_summary": {
    "status": "not_checked",
    "enabled_rewards": 2,
    "message": "Run promotions readiness before publishing."
  }
}
```

Readiness is not rechecked against Shopify after each design edit. Run
`lexsis_cart.promotions` before publishing. Summary warnings are bounded;
`warnings_omitted` tells you when to request the full response. If an edit
saves but its preview cannot be created, `preview_error` says it was saved:
retry `preview`, not the edit.

## Change one CSS block

`custom_css` **replaces all custom CSS, including named blocks**. Passing
`null` clears it. For an incremental change, use `patch.css_ops`:

```json
{
  "cart_profile_id": "PROFILE_UUID",
  "expected_version": 11,
  "patch": {
    "css_ops": [
      {"op": "upsert", "id": "checkout", "css": "[data-part=\"checkout\"] { font-weight: 700; }"},
      {"op": "remove", "id": "old-spacing"}
    ]
  }
}
```

Use an existing block ID for removal. Upserting keeps its original position;
new blocks append. The first incremental edit preserves existing replacement
CSS as a block named `legacy`. Blocks are concatenated in insertion order,
scoped to the cart, and validated individually and together. Remote URLs,
imports, script escapes and unbalanced rules are rejected. Do not send
`custom_css` and `css_ops` in the same patch.

## Open a sample cart on the real page

Call `lexsis_cart` with `action: "preview"`:

```json
{
  "page_id": "PAGE_UUID",
  "cart_profile_id": "PROFILE_UUID",
  "fixture": "all_unlocked"
}
```

The response contains a version-pinned `preview_url` valid for 15 minutes.
It creates no browser session. Open it using your browser or your agent's
existing browser tool. Omit `page_id` for an isolated cart preview.

Available states are `empty`, `below_first_reward`, `between_rewards`,
`all_unlocked`, `gift_chosen`, and `code_applied`. They use the profile's
thresholds, coupons and real synced catalogue variants. An unavailable gift,
missing coupon or unreachable threshold is reported explicitly. A profile
without the relevant feature cannot demonstrate that state.

For exact merchandise selection, provide a fixture object:

```json
{
  "page_id": "PAGE_UUID",
  "cart_profile_id": "PROFILE_UUID",
  "fixture": {
    "lines": [
      {"variantId": "gid://shopify/ProductVariant/123", "quantity": 2}
    ],
    "codes": ["SAVE10"]
  }
}
```

Replace the variant and code with real store values. Each line may include
`sellingPlanId`. The limits are 12 lines, quantity 1–999, and 10 codes.

Current previews use catalogue prices and the shared cart reward calculations,
reported as `source: "computed"`. Discount estimates are not Shopify checkout
quotes. Preview-only reward simulation can show unpublished rewards;
readiness warnings remain visible and publishing still requires readiness.

The page displays **Preview: sample cart**. Quantity, remove, add and custom
cart commands operate in memory. Checkout is blocked, tracking is suppressed,
and the fixture never reads or writes the shopper's `lx_cartId`. Reloading
restores the signed sample. A tampered or expired token logs `fixture_invalid`
and falls back to the normal cart; without the badge, you are no longer in a
sample-cart session.

## Inspect all six states

Call `lexsis_cart` with `action: "preview_states"`:

```json
{
  "page_id": "PAGE_UUID",
  "cart_profile_id": "PROFILE_UUID"
}
```

One result contains six entries with `preview_url`, the resolved `snapshot`,
module visibility, `static_checks`, and a `pass`, `warn`, `fail` or `not_run`
status. Static checks cover:

- Stored settings without a rendered effect.
- Configured text/surface, button-text/accent, muted/surface and reward color
  pairs against the 4.5:1 contrast threshold. Inherited or unresolved colors
  are `not_checked`.
- Unready rewards in visible reward modules.
- Custom module compilation errors.
- Hardcoded checkout links.

These checks do not measure DOM layout, overflow, actual font size, touch
targets or computed styles, and they do not produce screenshots. Open the
URLs at mobile and desktop sizes for visual review. No browser or screenshot
service is started by Lexsis.

## Request smaller island schemas

`lexsis_design.island_schema` returns a compact prop overview by default.
Repeated icon names appear once under `$defs.iconName`. Nested props marked
`expand: true` can be requested explicitly:

```json
{
  "name": "CartRewardProgress",
  "fields": ["rewards", "visuals"],
  "verbose": false
}
```

Use `verbose: true` for the full guidance, styling and examples. Shared
definitions use `$ref`; a `type_expression` preserves the authoring schema's
shape notation and can contain `$ref(#/$defs/iconName)` aliases. This is an
authoring contract, not a standalone JSON Schema validator.

## Related

- [Cart Profile Tools](/tools/cart)
- [Cart Lifecycle Through MCP](/guides/cart-lifecycle)
- [Custom Cart Modules](/guides/custom-cart-modules)
