---
title: Checkout Kit for Web
description: Embed Shopify checkout in your web app using the shopify-checkout web component.
source_url:
  html: https://shopify.dev/docs/storefronts/mobile-next/checkout-kit/web
  md: https://shopify.dev/docs/storefronts/mobile-next/checkout-kit/web.md
---

# Checkout Kit for Web

Embed Shopify checkout in your web app using Checkout Kit for Web. Open checkout in a new tab or a popup window from your page, and receive its lifecycle events, instead of redirecting buyers away. Checkout Kit for Web renders your store's branding, extensions, and payment settings.

Checkout Kit for Web supports checkout presentation, appearance configuration, telemetry and logging controls, and lifecycle events. Preloading and accelerated checkouts are available only in the native SDKs.

***

## What you'll learn

In this tutorial, you'll:

* Add Checkout Kit to your web app.
* Present checkout through a `checkoutUrl` or cart permalink.
* Configure checkout behavior with attributes.
* Listen for checkout events.

***

## Requirements

* A valid `checkoutUrl`. Get one from the [Storefront API](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/cart/manage#step-7-retrieve-a-checkout-url) `cart.checkoutUrl` field, the [Catalog MCP server](https://shopify.dev/docs/agents/catalog/global-catalog) or [Catalog API](https://shopify.dev/docs/api/catalog-api) product response (for agentic commerce), or a [cart permalink](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks).

***

## Step 1: Add Checkout Kit

Install the npm package for apps with a build step, or load Checkout Kit from Shopify's CDN as an ES module:

#### npm

Install the package and import the component entry point. This entry registers `<shopify-checkout>`:

```bash
npm install @shopify/checkout-kit
```

```javascript
import '@shopify/checkout-kit/shopify-checkout';
```

The package root (`@shopify/checkout-kit`) exports the classes, events, and types without registering anything. Import the component entry point, or call `ShopifyCheckout.register()`, before you render the element.

#### CDN

Import the loader and register the component you need:

```html
<script type="module">
  import {loadComponents} from 'https://cdn.shopify.com/checkout-kit/v4/checkout-kit.js';
  await loadComponents(['shopify-checkout']);
</script>
```

The URL is evergreen within a major version: compatible updates are delivered automatically, and a breaking change ships under a new major path. The loader also exports `version`, the Checkout Kit release it was built from.

***

## Step 2: Add the checkout element

Add a `<shopify-checkout>` element to your HTML. Use the `checkoutUrl` as the anchor's `href` so buyers can still reach checkout if the component fails to load:

## HTML

```html
<shopify-checkout></shopify-checkout>


<a id="checkout-button" target="_blank" href="https://{shop}.myshopify.com/cart/12345:1">
  Checkout
</a>
```

***

## Step 3: Present checkout

Set the `src` attribute to a `checkoutUrl` and call `open()`:

## JavaScript

```javascript
const checkout = document.querySelector("shopify-checkout");
const checkoutButton = document.querySelector("#checkout-button");


checkoutButton.addEventListener("click", (event) => {
  event.preventDefault();
  checkout.src = checkoutButton.href;
  checkout.open();
});
```

***

## Step 4: Listen for events

The `<shopify-checkout>` element dispatches `start`, `update`, `complete`, `error`, `close`, and `blocked` events. They don't bubble, so attach listeners to the element. Payloads are in `event.detail`:

## JavaScript

```javascript
const checkout = document.querySelector("shopify-checkout");


checkout.addEventListener("complete", (event) => {
  const { order } = event.detail.checkout;
  console.log("Order completed:", order?.id);
});


checkout.addEventListener("error", (event) => {
  const { code, message } = event.detail.error;
  console.error("Checkout failed:", code, message);
});


checkout.addEventListener("close", () => {
  console.log("Checkout closed");
});
```

| Event | `event.detail` | When it fires |
| - | - | - |
| `start` | `{checkout}` | Checkout has loaded and is interactive. |
| `update` | `{checkout}` | Line items, fulfillment, totals, or checkout messages changed. |
| `complete` | `{checkout}` | The buyer completed the order. The order is at `event.detail.checkout.order`. |
| `error` | `{error}` | Checkout couldn't open or reported a terminal error, as `{code, message}`. An open session closes after this event. |
| `close` | `null` | The session ended: `close()` was called, the overlay was dismissed, or the buyer closed the popup. |
| `blocked` | `{code}` | The browser blocked the checkout window, with `code` set to `"popup_blocked"`. |

If the browser blocks the checkout window, for example because `open()` ran outside a user gesture, then the element dispatches `blocked` with `code` set to `"popup_blocked"`. It fires on every blocked attempt, whether or not the overlay is shown. It doesn't close the session: the overlay stays open with a button to try again, and dismissing it dispatches `close`. If you hide the overlay, then show your own message from a `blocked` listener:

## JavaScript

```javascript
checkout.addEventListener("blocked", () => {
  showAllowPopupsMessage();
});
```

Call `open()` again from a user action, such as a click. The element ignores `open()` calls made directly from the `blocked` listener.

***

## Configuration

The `<shopify-checkout>` element accepts these attributes:

### `src`

Required. The `checkoutUrl` from the Storefront API or a cart permalink.

## HTML

```html
<shopify-checkout src="https://{shop}.myshopify.com/cart/c/abc123"></shopify-checkout>
```

### `target`

Where checkout opens. Defaults to `auto`.

* `auto`: Opens checkout in a new tab.
* `popup`: Opens checkout in a popup window centered over your page.
* `_blank`: Same as `auto`.
* Any other string is used as a named window target, like the `target` parameter of `window.open()`. `_self`, `_parent`, and `_top` aren't allowed and fall back to `auto`.

## JavaScript

```javascript
const checkout = document.querySelector("shopify-checkout");


checkout.setAttribute("target", "popup");
checkout.open();
```

With `target="popup"`, the popup defaults to 600 × 600 pixels, capped at 90% of the window. Override it with the `--shopify-checkout-dialog-width` and `--shopify-checkout-dialog-height` CSS custom properties on the element. While the popup is open, the element shows an overlay over your page with a link back to the checkout window and a close button; hide it with `display: none` on the element or on the `overlay` shadow part.

### `appearance`

The checkout appearance. Defaults to `storefront`, your store's checkout branding. Use `app:light`, `app:dark`, or `app:automatic` for Checkout Kit's own light or dark style.

## HTML

```html
<shopify-checkout appearance="app:dark"></shopify-checkout>
```

### `log-level`

Console logging verbosity: `debug`, `warn`, `error` (default), or `none`. Use `debug` while wiring up `src` and event handlers.

### `allowed-origins`

Extra origins allowed to send checkout protocol messages, in addition to the origin of `src` and Shopify's `shop.app` and `shop.com` domains. Separate entries with spaces or commas; `https://*.example.net` matches subdomains only. `*` disables the allowlist; use it only while debugging, never in production.

### `telemetry`

Anonymous diagnostic metrics sent to Shopify, enabled by default. Set `telemetry="false"` to opt out; changing it at runtime also discards buffered measurements. Diagnostics never include checkout URLs, message payloads, buyer data, or checkout, order, customer, or shop identifiers.

***

## Methods

* `open()`: Opens checkout at `src`. Call it from a user action, such as a click, so the browser allows the window.
* `close()`: Closes the open checkout window and the overlay.
* `focus()`: Brings the checkout window to the foreground.

***

## Browser support and considerations

Checkout Kit for Web supports Chrome, Chrome for Android, Edge, Firefox, and Firefox for Android 111 or later, and Safari and iOS Safari 16.4 or later.

The component relies on custom HTML elements and JavaScript modules. In older browsers it doesn't register, so keep the `checkoutUrl` on the anchor's `href` as a fallback that opens checkout in a new tab.

### Content Security Policy

Checkout opens in a separate window on the checkout origin and communicates with your page through `postMessage`, so your page doesn't frame or fetch checkout. If you load Checkout Kit from the CDN, allow `cdn.shopify.com` in your CSP `script-src` directive.

***

## Next steps

[About accelerated checkouts\
\
](https://shopify.dev/docs/storefronts/mobile/checkout-kit/accelerated-checkouts-overview)

[Add Shop Pay and Apple Pay buttons for one-tap purchases on product and cart pages.](https://shopify.dev/docs/storefronts/mobile/checkout-kit/accelerated-checkouts-overview)

[Set up accelerated checkouts\
\
](https://shopify.dev/docs/storefronts/mobile/checkout-kit/accelerated-checkouts)

[Install the package, configure Apple Pay, add buttons, and handle events.](https://shopify.dev/docs/storefronts/mobile/checkout-kit/accelerated-checkouts)

***