Checkout
Preview Available in release assets
Collect non-payment checkout information in ordinary server-submittable steps while leaving payment collection to a secure integration.
Server contract
GET or POST /api/advanced/cart-checkout?view=checkout renders the complete server-owned checkout view for native navigation; a Datastar request to the same action returns the stable fragment only. Never embed payment controls or treat browser state as commerce truth.
Cart lines, checkout forms, discounts, availability notices, totals, errors, and order progress remain server-rendered and usable without JavaScript.
Checkout primary example
<main class="thin-checkout" aria-labelledby="checkout-title">
<header>
<nav aria-label="Checkout progress">
<ol>
<li aria-current="step">Delivery</li>
<li>Review</li>
<li>Payment on secure provider</li>
</ol>
</nav>
<h1 id="checkout-title">Checkout</h1>
</header>
<div class="thin-checkout-layout">
<form action="/checkout/delivery" method="post" novalidate>
<div class="thin-checkout-errors" role="alert">
<h2>Check your delivery details</h2>
<ul>
<li><a href="#postal-code">Enter a valid postal code.</a></li>
</ul>
</div>
<fieldset>
<legend>Contact</legend>
<div class="thin-field">
<label for="checkout-email">Email</label>
<input class="thin-input" id="checkout-email" name="email" type="email" autocomplete="email" value="ryan@example.com" required />
</div>
</fieldset>
<fieldset>
<legend>Delivery address</legend>
<div class="thin-field">
<label for="postal-code">Postal code</label>
<input class="thin-input" id="postal-code" name="postal_code" autocomplete="postal-code" aria-invalid="true" aria-describedby="postal-code-error" required />
<p id="postal-code-error">Enter a valid postal code.</p>
</div>
</fieldset>
<button class="thin-button">Continue to review</button>
</form>
<aside class="thin-order-summary" aria-labelledby="checkout-summary-title">
<h2 id="checkout-summary-title">Order summary</h2>
<p>2 × Everyday canvas tote</p>
<dl>
<div>
<dt>Subtotal</dt>
<dd>$136.00</dd>
</div>
<div>
<dt>Estimated total</dt>
<dd>$136.00</dd>
</div>
</dl>
<p>Final shipping, tax, discounts, and availability are calculated after submission.</p>
<a href="/cart">Edit cart</a>
</aside>
</div>
</main>Show code
<main class="thin-checkout" aria-labelledby="checkout-title">
<header>
<nav aria-label="Checkout progress">
<ol>
<li aria-current="step">Delivery</li>
<li>Review</li>
<li>Payment on secure provider</li>
</ol>
</nav>
<h1 id="checkout-title">Checkout</h1>
</header>
<div class="thin-checkout-layout">
<form action="/checkout/delivery" method="post" novalidate>
<div class="thin-checkout-errors" role="alert">
<h2>Check your delivery details</h2>
<ul>
<li><a href="#postal-code">Enter a valid postal code.</a></li>
</ul>
</div>
<fieldset>
<legend>Contact</legend>
<div class="thin-field">
<label for="checkout-email">Email</label>
<input class="thin-input" id="checkout-email" name="email" type="email" autocomplete="email" value="ryan@example.com" required />
</div>
</fieldset>
<fieldset>
<legend>Delivery address</legend>
<div class="thin-field">
<label for="postal-code">Postal code</label>
<input class="thin-input" id="postal-code" name="postal_code" autocomplete="postal-code" aria-invalid="true" aria-describedby="postal-code-error" required />
<p id="postal-code-error">Enter a valid postal code.</p>
</div>
</fieldset>
<button class="thin-button">Continue to review</button>
</form>
<aside class="thin-order-summary" aria-labelledby="checkout-summary-title">
<h2 id="checkout-summary-title">Order summary</h2>
<p>2 × Everyday canvas tote</p>
<dl>
<div>
<dt>Subtotal</dt>
<dd>$136.00</dd>
</div>
<div>
<dt>Estimated total</dt>
<dd>$136.00</dd>
</div>
</dl>
<p>Final shipping, tax, discounts, and availability are calculated after submission.</p>
<a href="/cart">Edit cart</a>
</aside>
</div>
</main>Anatomy
- Checkout progress
- Server validation summary
- Labelled delivery form
- Order summary
- Durable cart link
Variants and sizes
- Neutral theme
- Thin-Sky theme
- Intrinsic narrow and wide containers
Gallery coverage: No structured variant fixtures are published yet; the primary example above is the only verified production markup.
States and difficult content
Rendered fixtures exercise authored content and constrained layouts with the same production assets.
- Delivery
- Review
- Invalid
- Submitting
- Server error
- Availability changed
- Long localized content
Structured state fixtures are not published for this item yet.
Interaction and keyboard behavior
Normal links and forms navigate and submit to server routes. Returned HTML owns prices, inventory, discounts, validation, totals, and order state.
Accessibility
Use landmarks, headings, labelled native controls, linked error summaries, visible status text, logical reading order, and non-color state cues. Move focus on server navigation, not speculative client updates.
- Contract
COMPOSE- Basis
- Native forms, tables/lists, headings, links, and status content; no APG widget
- Evidence
tests/unit/library/cart-checkout.test.ts
API
GET or POST /api/advanced/cart-checkout?view=checkout renders the complete server-owned checkout view for native navigation; a Datastar request to the same action returns the stable fragment only. Never embed payment controls or treat browser state as commerce truth.
Behavior tier: dependency-free
Structured host, property, and example tables are not authored for this item yet. Use the summary above and the primary example.
Fallback
Cart lines, checkout forms, discounts, availability notices, totals, errors, and order progress remain server-rendered and usable without JavaScript.
Assets and dependencies
/foundation.css/layouts.css/components.css/patterns/ecommerce.css
Dependencies: field, quantity-input, alert, status, steps
Source: packages/ui/src/style/ecommerce.ts
Composition
Derived from the examples and style specs, not authored.