Add managed Commerce carts and checkout web components - #1448
Open
wcole1-godaddy wants to merge 22 commits into
Open
Add managed Commerce carts and checkout web components#1448wcole1-godaddy wants to merge 22 commits into
wcole1-godaddy wants to merge 22 commits into
Conversation
🦋 Changeset detectedLatest commit: d98fb13 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
pbennett1-godaddy
approved these changes
Sep 8, 2026
wcole1-godaddy
marked this pull request as ready for review
September 8, 2026 18:45
- Hydrate once via a shared ready() promise that does not take the cross-tab write lock; mutations sync the saved ID and read the cart once inside the lock, with the SKU lookup in parallel
- Resolve the OAuth token before locking so a slow token callback cannot block other tabs
- Derive snapshot.status from pending/error; drop the unread checkoutSource field and the dead CART_CREATE_FAILED guard
- Release a saved cart that Commerce reports as not found via a GraphQL error
- Resolve relative return/success URLs against the page and raise CommerceError('INVALID_URL') from one shared helper used by the client and redirect
- Elements: replace localName checks with waitsForCart/badge hooks; render the cart count in ::part(count) so it survives slotted label text
- React: translate disabled/className into attributes so React 18 hosts work; useCart exposes the session as checkout, stable actions, and startCheckout
- Drawer: cache currency formatters and fall back on invalid locales; share itemCount
- Tests for hydration/locking, token-before-lock, not-found release, URL handling, derived status, cart badge, invalid hosted URL, and React attribute/action behavior
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A plain Vite page that configures @godaddy/commerce against a real Commerce environment, renders the add-to-cart, cart, and buy-now elements, and shows useCart() state. A dev-only Vite middleware performs the OAuth client-credentials grant server-side and hands the page a short-lived token for checkout. Documents that Commerce rejects localhost return/success URLs, so local runs must override them with public URLs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Drawer: replace hard-coded surface, text, control, and border colors with
--gddy-surface/--gddy-text/--gddy-subtle/--gddy-border/--gddy-muted/
--gddy-font/--gddy-color-scheme (same defaults); stop redefining theme
variables on .gddy-drawer so :root values from the host page win
- Buttons: chrome driven by --gddy-button-{background,border,shadow,padding,
min-height,weight}, --gddy-font, badge colors; built-in hover/press
feedback; `flat` attribute for a solid fill
- Client: optional createSession(input) delegate creates the hosted session on
the merchant's server so no Commerce token reaches the browser; scope check
tolerates omitted fields on server responses
- README: styling section with the variable table, parts, flat, and a shadcn
token-bridge example; document createSession
- Example: appearance panel emits variables instead of ::part rules, adds
drawer surface controls and a Dark preset; guard configureCommerce on HMR
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- The stepper container owns the corner radius (capped at 14px) and clips its children; the inner +/- buttons are square, so the hover fill follows the container instead of drawing its own rounded shape - Footer logo uses GoDaddy Everyday Teal 400 (#1BDBDB) per brand guidelines Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Whether a store accepts codes depends on the discounts GPA being enabled, and there is no storefront-safe way to read that yet; the storefront API also accepts unknown codes silently. Drop the form and its styles until a capability lookup exists. The headless applyDiscount API is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Use a 64px image (matching the rendered img size) and stack heading, options, and controls with a fixed 8px gap instead of bottom-aligning controls to an 80px min-height, so lines without variants have no dead space. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
addLineItemBySkuId stores the name we pass; sku.name is the catalog slug (the-structured-blazer-m) while hosted checkout shows the label. Prefer the label so the drawer and hosted checkout agree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The image column stretches to the content height (56px without variants, 80px with one variant row), so its top meets the title and its bottom meets the controls on every line. The price shares the title's 20px line height. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stretching the image column to the content height distorted product art on lines with variants. The thumbnail is a fixed 80px square again and the line content centers against it, so plain lines sit balanced and one-variant lines fill the row edge to edge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A long product name now truncates with an ellipsis after two lines instead of growing the row without limit. The full name stays available through the title attribute and the control labels. Line content hangs from the top of the row next to the thumbnail, so a tall line grows downward instead of floating the image to the middle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each element tracks its own click action and reflects it as a busy attribute. While busy, the label hides and a ring in ::part(spinner) takes its place, so the button keeps its size; the button reads as working rather than unavailable. Buy now and Pay now stay busy after a successful redirect and clear when the page is restored from the back/forward cache. The drawer's checkout button gets the same ring next to its updating text. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Only the line items carry separators now. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rows are set apart by their padding and thumbnails alone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The gaps below the divider were 19, 10, 12, 17 and 13px. They are now 16px around each block with 4px between the subtotal and its note. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
createSession is now the supported checkout path. It receives a SessionRequest that includes the payment reference for pay(), so the server prices and creates the session and the browser never holds a Commerce OAuth token. getAccessToken still works but throws unless dangerouslyAllowBrowserToken is set, because any token that can create a session can also act on the merchant's orders. The commerce-elements example swaps its dev token endpoint for a /api/commerce/checkout route that calls createCheckoutSession on the server side of Vite. Docs, changeset, and tests follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pnpm build:cdn produces cdn/: a classic-script loader, commerce.js, that imports a content-hashed runtime chunk relative to its own URL, plus hashed immutable chunks for the drawer (with its own React), the redirect helper, and the stylesheet, and a manifest with version, commit, and file list. The runtime registers the elements, exposes window.GddyCommerce with release info, applies window.gddyCommerceConfig, links the stylesheet, and fires gddy:ready. cdn:serve serves cdn/ locally under /v1/ with production headers for chunks and no-store for the loader. The commerce-elements example gains cdn.html, a plain HTML storefront that loads the runtime from a script tag. The checkout repository deploys the build from a git ref, so component updates ship without an npm release. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The drawer padded with var(--gddy-gutter) and nothing else, so it only had a gutter when the page defined the variable, as the example's theme panel does. Every use now falls back to 16px like the other tokens, and the README lists the variable. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The runtime entry, loader, and CDN build move to the protected checkout repository, which builds them from a git ref of this package. The README keeps the browser contract (classic-script entry, window.GddyCommerce, gddy:ready, gddy:error, immutable chunks) so both sides implement the same thing. The example's cdn.html stays as a consumer of whatever URL VITE_COMMERCE_CDN_URL names. Co-Authored-By: Claude Fable 5.1 <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.
Websites need a consistent way to manage multi-product carts and one-time purchases without rebuilding cart state or assembling React providers. This adds
@godaddy/commerce, a framework-independent library over the existing Commerce APIs and an application's OAuth client. Shoppers review a managed cart drawer, then continue to hosted checkout.18.x || 19.xpeers, with React 19 retained for development, so npm consumers share their host renderer.gddy-add-to-cart,gddy-cart-button,gddy-buy-now, andgddy-payment-button, with optional React bindings and a headless client.@godaddy/react/clientexport. Supporting@godaddy/reactchanges include embedded completion callbacks, session-scoped authentication storage, and style/portal scoping for that component's consumers; the managed Commerce elements use hosted checkout.Validation of the latest changes:
git diff --checkpassed.useCart, the cart button, drawer rendering, and typed quantity commits. The regular Commerce suite runs on React 19.0d8c7d5e80c2413937f92c536c339266599a9655.This remains a draft and the npm package is unreleased. The protected checkout repository owns CDN bundling, infrastructure, and release automation; this PR does not deploy a CDN release. Schema verification used synthetic data and snapshot contracts, including a downstream Orders snapshot. Real-store authorization, deployed API compatibility, and live payments remain untested. Draft creation still sends accepted but deprecated zero-valued totals; this is a non-blocking schema finding.