# Buy button for your token

> Add a "Buy $TOKEN" button to your project's site with one script tag. Visitors pay with any token on any chain in a LayerHop window over your page; no account or API key needed.

Source: https://docs.layerhop.com/guides/buy-button

The buy button is a small script (about 3 KB gzipped, no dependencies) that puts a "Buy $YOURTOKEN" button on your page. A click opens the LayerHop [swap widget](/guides/embed-widget) in a window over your site, with your token locked as the token the visitor receives. They pay with any token on any of the 71 supported chains and sign in their own wallet. Swaps go through the `widget` [fee channel](/concepts/fees-and-channels), exactly like the embedded widget.

## 1. Make it in the button builder

Open the [button builder](https://app.layerhop.com/button). Search for your token, set the label, theme and color, add your partner id if you have one, and click the preview: it is the real button. Copy the script tag, the React component or a plain link. From any token page on [app.layerhop.com](https://app.layerhop.com), **Share → Get a buy button** opens the builder with that token filled in.

## 2. Paste the script tag

Put the tag where the button should appear:

```html
<script async src="https://app.layerhop.com/buy.js"
  data-chain="solana"
  data-token="DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
  data-label="Buy $BONK"
></script>
```

The script inserts the button right after itself. A tag placed in `<head>` puts the button at the start of `<body>` instead, and `data-target` (a CSS selector) puts it inside that element, waiting for the page to load if needed. You can add several tags for several tokens on one page.

| Attribute | Example | Meaning |
|---|---|---|
| `data-chain` | `solana` | Required. Chain slug or id of your token |
| `data-token` | `DezXAZ8z…` | Required. Token address or mint |
| `data-label` | `Buy $BONK` | Button text, up to 32 characters (default `Buy`). Also the widget's title, and its main button label when it fits in 24 characters |
| `data-theme` | `light` | `dark` (default) or `light`: the button's default color and the widget's theme |
| `data-color` | `22d3ee` | Button color, hex with or without `#`. The text turns dark or white for contrast. Also the widget's accent |
| `data-integrator` | `myproject` | Your partner id (see below) |
| `data-target` | `#buy-slot` | CSS selector of the element to put the button in (default: right after the script tag) |

Invalid values are ignored and the default is used, the same rules as the [widget parameters](/widget-reference).

## 3. Or use React

React does not run `<script>` tags in JSX, so the component adds the script itself:

```tsx
import { useEffect, useRef } from "react";

export function BuyButton() {
  const ref = useRef<HTMLSpanElement>(null);
  useEffect(() => {
    const host = ref.current;
    if (!host) return;
    const s = document.createElement("script");
    s.src = "https://app.layerhop.com/buy.js";
    s.dataset.chain = "solana";
    s.dataset.token = "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263";
    s.dataset.label = "Buy $BONK";
    host.appendChild(s);
    return () => host.replaceChildren();
  }, []);
  return <span ref={ref} />;
}
```

Once the script has loaded, `window.LayerHopBuy` also has `mount(element, options)` (returns `{ destroy }`), `open(options)` and `close()`, with the same option names as the attributes (`chain`, `token`, `label`, `theme`, `color`, `integrator`).

## 4. Or link to the token page

No script at all: link to your token's page on the LayerHop app, opened on the Buy side.

```text
https://app.layerhop.com/token/solana/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263?side=buy
```

Token pages exist for Solana and Robinhood Chain tokens. Add `&amount=50` to prefill a $50 buy paid in USDC (up to $1,000); the visitor still picks what to pay with, reviews and signs.

## Earn partner fees

`data-integrator` is the same partner id as the widget's `integrator` parameter. When it belongs to a registered partner, your fee is added on top of LayerHop's and shown to the buyer as its own line before they sign. Unknown ids are ignored, so the button works before you are approved. See [Earn fees as a partner](/guides/partner-fees).

## Events

While the window is open, the button re-dispatches the widget's [events](/widget-reference) on its element as DOM events named `layerhop:<type>` (for example `layerhop:submitted` and `layerhop:status`), with the payload in `event.detail`. They bubble, so you can listen on `document`:

```js
document.addEventListener("layerhop:status", (e) => {
  if (e.detail.state === "filled") console.log("Bought!", e.detail.srcTxHash);
});
```

## Is it safe for my visitors?

- **It only opens LayerHop.** The window always loads `https://layerhop.com/embed`, whatever page or copy of the script it runs from.
- **Messages are checked.** The script only reads messages whose origin is LayerHop, that come from its own window and that use the widget's message format.
- **Minimal permissions.** The window gets `clipboard-write` and nothing else. No cookies are set on your site, and it needs no third-party cookies.
- **Non-custodial.** The visitor's own wallet signs every transaction; LayerHop never holds funds or keys. See [Non-custodial by design](/concepts/non-custodial).
- **Isolated styles.** The button and window render in a shadow root, so your CSS can't break them and theirs never leaks into your page.

## Related

- [Embed the widget](/guides/embed-widget): the full widget, with every customization.
- [Widget customization reference](/widget-reference): parameters and events.
- [Earn fees as a partner](/guides/partner-fees).
