feat(apps-vtex): Cart v2 — modular, granular, framework-agnostic cart#374
Open
JonasJesus42 wants to merge 1 commit into
Open
feat(apps-vtex): Cart v2 — modular, granular, framework-agnostic cart#374JonasJesus42 wants to merge 1 commit into
JonasJesus42 wants to merge 1 commit into
Conversation
Introduces a two-dimension fragmentation system for the VTEX cart:
- `sections` (expectedOrderFormSections) — limits what VTEX computes
- `projection` (none/summary/summary+items/minicart/raw) — limits what goes to the browser
Key outcomes vs the legacy cart:
- Lazy: no OrderForm created until first add-to-cart (eliminates the eager
mount-time VTEX call for browsing-only visitors)
- Default add-to-cart sends only SECTIONS_MINIMAL (3 sections instead of 15)
and returns a slim `{ totalItems, total, items:[slim] }` to the browser
- Optimistic badge bump + server reconciliation built into the hook; storefront
never re-implements this logic
New files:
- packages/apps-commerce/src/types/cart.ts — agnostic contract (CartSection,
CartProjection, CartSummary, CartItemSlim, SECTIONS_MINIMAL/DRAWER/FULL)
- packages/apps-vtex/src/utils/cartProjection.ts — projectOrderForm()
- packages/apps-vtex/src/loaders/cart/{summary,full,shipping,gifts,attachments}
- packages/apps-vtex/src/hooks/createCart.ts — factory (useCart, useCartSummary,
useAddToCart, useShipping, useGifts, useAttachments, resetCart)
- packages/apps-vtex/src/hooks/cartQuery.ts — optional TanStack Query adapter
with 6 hooks (useShipping keyed by {postalCode,items} for client-side cache)
- .agents/skills/vtex-cart-v2/SKILL.md — full usage, projection decision guide,
gradual migration guide
Modified:
- actions/checkout.ts: addItemsToCartV2/updateCartItemsV2/addCouponToCartV2/
getOrCreateCartV2 + unified DEFAULT_EXPECTED_SECTIONS from SECTIONS_FULL
- invoke.ts: v2 action entries for generate-invoke TanStack createServerFn
- manifest.gen.ts: 5 new vtex/loaders/cart/* entries
- apps-vtex package.json: @tanstack/react-query as optional peerDep
add() returns the projected payload so callers can drive a toast without a
second fetch; updateQuantity/removeItem/addCoupon return the projected Minicart.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a two-dimension cart fragmentation system for
@decocms/apps-vtex:sections(controls what VTEX computes viaexpectedOrderFormSections) andprojection(none/summary/summary+items/minicart/raw, controls what the server sends to the browser). The result: no OrderForm created until the first add-to-cart, add-to-cart sends 3 sections instead of 15, and the browser receives ~1 KB instead of ~40 KB by default. Optimistic badge bump + server reconciliation live in the hook — the storefront never reimplements them. The agnostic contract lives in@decocms/apps-commerce(Shopify/Wake can reuse the same types). Includes a TanStack Query adapter (6 hooks,useShippingkeyed by{postalCode,items}for client-side cache), 281 passing tests, and a skill with usage guide, projection decision table, and gradual v1→v2 migration guide.New surface
@decocms/apps-commerce/types/cart—CartSection,CartProjection,CartSummary,CartItemSlim,SECTIONS_MINIMAL/DRAWER/FULLvtex/loaders/cart/{summary,full,shipping,gifts,attachments}— granular read-path loaders, each requesting only the sections it needscreateCart({ invoke })— factory:useCart,useCartSummary,useAddToCart,useShipping,useGifts,useAttachments,resetCart;add()returns the projected payload for toasts without a second fetchcreateCartQuery({ invoke })— optional TanStack Query adapter with full parityactions/checkout.ts:addItemsToCartV2,updateCartItemsV2,addCouponToCartV2,getOrCreateCartV2.agents/skills/vtex-cart-v2/SKILL.md— full usage, projection decision guide, gradual migration guideTest plan
vitest run packages/apps-vtex packages/apps-commerce— 281 tests passing (26 files)tsc --noEmitonapps-vtexandapps-commerce— 0 errorsbiome check— 0 errors on all touched files/api/checkout/pub/orderForm; add-to-cart → body containsSECTIONS_MINIMAL, response is slimsummary+items; open drawer →cart/fullcalled with 9 sections🤖 Generated with Claude Code
Summary by cubic
Cart v2 for
@decocms/apps-vtexadds two-way cart fragmentation (sectionsandprojection) to cut VTEX compute and shrink client payloads. No cart is created until the first add; add-to-cart requests only minimal sections and returns a slim response with optimistic badge updates.New Features
@decocms/apps-commerce/types/cartwithSECTIONS_MINIMAL,SECTIONS_DRAWER, andSECTIONS_FULL.vtex/loaders/cart/{summary,full,shipping,gifts,attachments}.createCart({ invoke })hooks:useCart,useCartSummary,useAddToCart,useShipping,useGifts,useAttachments,resetCart(optimistic bump + server reconciliation;add()returns the projected payload).createCartQuery({ invoke });@tanstack/react-queryis an optional peer.getOrCreateCartV2,addItemsToCartV2,updateCartItemsV2,addCouponToCartV2with server-sideprojectOrderFormto enforce projections.Migration
useCartSummary+vtex/loaders/cart/summaryfor the badge.vtex/loaders/cart/full.createCartQuery; otherwise usecreateCart.Written for commit aed1d8c. Summary will update on new commits.