# Elements security and CSP

> How Elements work, what your page can and cannot see, allowed websites, Content Security Policy and nonces, and the known limits.

Source: https://shopfa.st/docs/elements/security

## How it works

Each element is a frame from your store's own address, and one hidden frame, the **controller**, holds the cart:

- **The controller** is the only part that talks to your store. It keeps the cart in memory as a sealed token
  (encrypted, tied to your page's address, valid for two hours and renewed with every change). There are no cookies, so
  Safari and Firefox, which block cookies in frames, work exactly like Chrome.
- **Elements** send what the buyer types straight to the controller, frame to frame, and draw the one state the
  controller sends back. That is why two elements can never disagree about the total.
- **Your page** creates the frames, sizes them and gets events. Every message is checked on arrival: the sender's
  address, the exact frame, a channel id unique to each `elements()` call, and its shape. Anything else is dropped.

## What your page can and cannot see

| Your page gets | Your page never gets |
| --- | --- |
| The cart: lines, quantities, codes and totals | The buyer's email, name, address or answers |
| Which fields are complete or empty | What the buyer typed |
| The way to pay and country picked | Card details (they never reach Elements either: card fields are the provider's) |
| The order number, total and order page link | The order's access, keys or downloads |

## Allowed websites

Your elements only open on websites you list in **Settings → Developers → Embeds → Allowed websites**, the same list
your product cards and checkout popup use. Each element frame sends a `frame-ancestors` policy built from that list, so
browsers refuse to show them anywhere else, and your store refuses the controller's calls from any other page.

Always allowed, whatever the list says:

- the [Elements playground](https://shopfa.st/docs/elements/playground) on shopfa.st and your dashboard's preview,
- `http://localhost` and `http://127.0.0.1` on any port, so you can build your page on your own computer,
- **any website while your store is in test mode**, so you can try Elements before you list anything.

On a website that is not allowed, the elements say the checkout cannot open there, and your page gets a `loaderror`
and an `error` with `origin_not_allowed`.

## Content Security Policy

If your site sends a CSP, allow your store's address for frames and the script:

```text
frame-src https://lumenfold.shopfa.st;
script-src https://lumenfold.shopfa.st;
```

Using nonces? Pass yours and the script puts it on every frame and style tag it adds:

```js
const shopfast = ShopFast({ nonce: "r4nd0m" });
```

The overlay checkout (buy and cart buttons) styles itself through a stylesheet in its own shadow root, so it needs no
`style-src` change in current browsers.

## What keeps the total honest

- **Your store decides** every price, discount, tax amount, way to pay and the EU and UK box. The elements show what it
  decided and send what the buyer typed; the store checks it all again when the buyer pays.
- **Rules are sanitized** before they reach a frame: one class from a published list, a fixed list of properties, and
  totals, the pay button, prices and legal texts accept only cosmetic changes. See [What is refused](https://shopfa.st/docs/elements/styling#what-is-refused).
- **A first layer of protections** in each frame keeps protected parts visible whatever a rule says.
- **Each element checks itself** after your rules apply, and turns them off if a protected part ends up hidden,
  outside the element or unreadable.

## Known limits

- **Script tag only.** No npm package or React wrapper yet; the [type definitions](https://shopfa.st/docs/elements/shopfast-elements.d.ts) cover the script.
- **One currency.** Elements charge in your store's currency.
- **Card fields open in the payment window.** Stripe's card step, PayPal and crypto open in a small window from your
  store rather than inside the payment element. Test mode pays right in the element.
- **Store credit** needs a signed-in buyer, so it is not offered in Elements. Gift cards work in the coupon field.
- **Auto-renew boxes** are not offered in Elements yet. Subscriptions sold through Elements renew with a pay link by email.
- **Elements and the controller must be on the same page**, not in a frame of their own.
