> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Mount and options

> Place an Elements checkout with HTML, Shoppex.mount or React, and every option it takes.

There are three ways to place a checkout block. All three load the same script and take the same options.

| Way | Use it when |
| - | - |
| [HTML block](#html-block) | Your site builder lets you paste HTML. No JavaScript needed. |
| [`Shoppex.mount`](#mount-with-javascript) | You want to listen to events, change the appearance later, or remove the block. |
| [React](#react) | Your site is a React app. |

## The script

```html theme={"system"}
<script src="https://checkout.shoppex.io/embed/embed.iife.js" defer></script>
```

It is the same script as the [Buy Button](/developers/embeds/overview). Add it once per page. To check that the loaded script supports Elements, read `Shoppex.supports.mount`.

## HTML block

```html theme={"system"}
<div
  data-shoppex-element="checkout"
  data-shoppex-shop-id="YOUR_SHOP"
  data-shoppex-product-id="YOUR_PRODUCT_ID"
  data-shoppex-quantity="1"
  data-shoppex-mode="test"
  data-shoppex-appearance='{"mode":"dark","colors":{"accent":"#22C55E"},"radius":10}'
></div>
```

The script mounts every `data-shoppex-element="checkout"` it finds, also ones your page adds later. Only `checkout` is supported as a value.

| Attribute | Value |
| - | - |
| `data-shoppex-element` | `checkout` |
| `data-shoppex-shop-id` | Your shop's slug. Required. |
| `data-shoppex-product-id` | The product to sell. Use this, `data-shoppex-items` or `data-shoppex-group-id`. |
| `data-shoppex-quantity` | Whole number, default `1`. A value below 1 or not a number becomes `1`. |
| `data-shoppex-price-variant-id` | The price variant. `data-shoppex-variant-id` also works. |
| `data-shoppex-items` | JSON with exactly one item: `[{"productId":"…","quantity":2}]` |
| `data-shoppex-group-id` | A product group. The buyer picks the product in the block. |
| `data-shoppex-mode` | `live` (default) or `test`. See [Test mode](/developers/elements/test-mode). |
| `data-shoppex-appearance` | JSON. See [Appearance](/developers/elements/appearance). Use single quotes around the attribute. |
| `data-shoppex-locale` | The buyer's language, for example `de`. Default: the browser's language. |
| `data-shoppex-coupon-code` | A coupon to apply. |
| `data-shoppex-email` | The buyer's email, filled in. |

JSON the script cannot read is named in the console as `Invalid data-shoppex-appearance JSON` and left out. The HTML block sends its events as DOM events on the `<div>`. See [DOM events](/developers/elements/events#dom-events).

## Mount with JavaScript

```html theme={"system"}
<div id="checkout"></div>

<script src="https://checkout.shoppex.io/embed/embed.iife.js" defer></script>
<script type="module">
  const checkout = Shoppex.mount('#checkout', {
    shopId: 'YOUR_SHOP',
    items: [{ productId: 'YOUR_PRODUCT_ID', quantity: 1 }],
    mode: 'test',
    appearance: { mode: 'dark', colors: { accent: '#22C55E' }, radius: 10 },
  });

  checkout.on('ready', ({ height }) => console.log('Block ready', height));
  checkout.on('success', ({ invoiceId }) => console.log('Order placed', invoiceId));
  checkout.on('error', ({ code, recoverable }) => console.warn(code, recoverable));
</script>
```

The script tag has `defer`, so `Shoppex` exists only after the page is parsed. Call `Shoppex.mount` from a `type="module"` script, which runs after it, or from your own code that runs after load.

`Shoppex.mount(target, options)` takes a CSS selector or an element and returns the block.

| Option | Type | |
| - | - | - |
| `shopId` | `string` | Your shop's slug. Required. |
| `items` | `[{ productId, quantity?, priceVariantId?, variantId? }]` | Exactly one product. Use this, `groupId` or `invoiceId`. `quantity` is a whole number from 1 to 999999. |
| `groupId` | `string` | A product group. |
| `invoiceId` | `string` | An invoice your server created with the [Developer API](/developers/invoices). The block opens at its payment step. |
| `mode` | `'live' \| 'test'` | Default `live`. Test mode needs `items`. |
| `appearance` | `object` | See [Appearance](/developers/elements/appearance). |
| `locale` | `string` | The buyer's language. Default: `Shoppex.init({ locale })`, then the browser's language. |
| `couponCode` | `string` | A coupon to apply. |
| `email` | `string` | The buyer's email, filled in. |
| `minHeight` | `number` | Pixels the block never shrinks below. |
| `debug` | `boolean` | Logs every message between the page and the block to the console, also the ones it dropped. |

Options the script cannot use do not throw. The block shows "Checkout didn't load", and your page gets the `invalid_options` error with the reason in the console.

### The block

| Method | |
| - | - |
| `on(type, listener)` | Adds a listener for an [event](/developers/elements/events). Returns a function that removes it. |
| `off(type, listener)` | Removes a listener. |
| `update({ appearance })` | Restyles the open block. Pass the whole appearance: it replaces the previous one. |
| `destroy()` | Removes the block and its listeners. |

An error from `mount` itself, like `invalid_options` or `already_mounted`, arrives after `mount` returns, so a listener you add right away hears it.

### One block per page

A page holds one Elements checkout. A second `Shoppex.mount` reports `already_mounted` and leaves the first block working. Call `destroy()` on the first block before you mount another.

In a single-page app, call `destroy()` when the route leaves. A block whose element was removed from the page without `destroy()` is cleaned up by the next `mount`.

## React

```bash theme={"system"}
npm install @shoppexio/checkout-js
```

```tsx Checkout.tsx theme={"system"}
import { ShoppexInlineCheckout } from '@shoppexio/checkout-js/react';

export function Checkout() {
  return (
    <ShoppexInlineCheckout
      shopId="YOUR_SHOP"
      items={[{ productId: 'YOUR_PRODUCT_ID', quantity: 1 }]}
      mode="test"
      appearance={{ mode: 'dark', radius: 10 }}
      onSuccess={(event) => console.log('Order placed', event.invoiceId)}
      onError={(event) => console.warn(event.code, event.recoverable)}
    />
  );
}
```

`<ShoppexInlineCheckout>` renders a `<div>` and mounts the block into it with the same script. It takes every option above as a prop, plus `onReady`, `onSuccess`, `onError`, `onEvent` (every event), `className` and `style`. A new `appearance` restyles the block in place. A change to any other prop mounts a new block. It needs `@shoppexio/checkout-js` 0.9.0 or later.

Without React, the package exports `mount(target, options)` with the same options and block methods. It loads the script for you.

## Global settings

`Shoppex.init` sets values for every block and buy button on the page:

```js theme={"system"}
Shoppex.init({ nonce: 'YOUR_NONCE', locale: 'de' });
```

| Setting | |
| - | - |
| `nonce` | Your CSP nonce. The script puts it on the styles it adds. See [Security and CSP](/developers/elements/security). |
| `locale` | The default language for every block. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.