# STON.fi (swap) Widget

The STON.fi widget is a ready-to-use swap interface for your app or website. Simply embed our lightweight script, and your users get full swap functionality instantly — while you earn fees from every swap.

<figure><img src="https://1159777691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCJ1ZKietYw2GrKAuOqA8%2Fuploads%2Fgit-blob-0ac5824eb51d99c2021b1fb24980838eb9306f28%2FSTON.fi%20widget.png?alt=media" alt=""><figcaption></figcaption></figure>

Quick setup, zero overhead. Start with the default configuration or customize it to match your brand. Delivered via CDN-hosted bundle for maximum performance. Looks and behaves like a native part of your UI.

### Try it with Lovable

Want to see the widget in action quickly? Use Lovable to generate a working example:

<a href="https://lovable.dev/?autosubmit=true#prompt=Build%20a%20simple%20webpage%20with%20the%20STON.fi%20swap%20widget%20integrated.%20No%20need%20to%20style%20it%20fancy.%20I%20just%20need%20a%20simple%20page%20with%20TON%20token%20swaps%20via%20the%20widget.%20After%20implementation%2C%20inform%20the%20user%20that%20if%20they%20see%20%27Failed%20to%20load%20Manifest%3A%20404%27%20that%27s%20because%20they%20are%20in%20Lovable%20website%20and%20testing%20it%20in%20preview%20mode.%20Tell%20them%20to%20publish%20the%20app%2C%20then%20manually%20replace%20the%20URL%20in%20manifest.json%20with%20the%20published%20URL%2C%20and%20then%20publish%20the%20app%20again%20after%20changes.%20If%20the%20user%20is%20in%20free%20credit%20mode%20and%20can%27t%20manually%20change%20the%20manifest%2C%20they%20should%20prompt%20and%20paste%20the%20URL%20so%20the%20agent%20will%20replace%20the%20manifest%20URL.%20Then%20tell%20them%20to%20go%20to%20the%20published%20URL%20to%20test%20the%20connection.%20Documentation%20is%20available%20at%20https://docs.ston.fi/developer-section/widget/widget" class="button primary">🚀 Build with Lovable</a>

Click the button above to automatically generate a working webpage with the STON.fi (swap) Widget integrated.

> ⚠️ **Note:** If you see 'Failed to load Manifest: 404' that's because you are in Lovable website and you test it in preview mode. Publish the app, replace the URL inside `manifest.json` with the published URL, and then publish the app again after changes. If you're in free credit mode and can't manually change the manifest, prompt and paste the URL so the agent will replace it. Then go to the published URL to test the connection.

You can also follow along with a recorded walkthrough:

{% embed url="<https://www.youtube.com/watch?v=zESpTWxka2s>" %}

### Integrate it yourself

If you want to integrate the widget yourself, continue reading below.

Two ways to embed:

1. **Via NPM loader** (for modern builds): Let the loader fetch the optimized bundle at runtime.
2. **Direct CDN script** (for simplicity): Drop one line of code into your project.

Both methods expose the same `OmnistonWidget` constructor, giving you full control.

* **`@ston-fi/omniston-widget-loader`** ([npm](https://www.npmjs.com/package/@ston-fi/omniston-widget-loader/v/latest)) – npm package that downloads the CDN bundle when you call `load()`.
* **CDN script** – zero-build option that exposes `window.OmnistonWidget` in modern browsers:

```html
  <script src="https://widget.ston.fi/v0/index.js"></script>
```

CDN URLs are **major-versioned** (`/v0/`, `/v1/`, ...). You receive all non-breaking updates within a major; bump the major path to adopt breaking changes.

## Quick start in 30 seconds

1. Host your [TON Connect manifest](https://docs.ton.org/v3/guidelines/ton-connect/creating-manifest) on your domain.
2. Choose CDN (no build) or npm (frameworks).
3. Paste one snippet to mount the widget; see [Full Guide](https://docs.ston.fi/developer-section/widget/widget) for full examples.

**Option A — CDN (no build)**

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>STON.fi (swap) Widget via CDN</title>
  </head>
  <body>
    <div id="omniston-widget-container" style="max-width: 420px; margin: 0 auto;"></div>

    <script src="https://widget.ston.fi/v0/index.js"></script>
    <script>
      const widget = new window.OmnistonWidget({
        tonconnect: {
          type: 'standalone',
          options: {
            // see https://docs.ton.org/ecosystem/ton-connect/manifest
            manifestUrl: 'https://[myapp.com]/tonconnect-manifest.json',
          },
        },
        widget: {
          // Optional: defaultBidAsset: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', // TON
          // Optional: defaultAskAsset: 'EQA2kCVNwVsil2EM2mB0SkXytxCqQjS4mttjDpnXmwG9T6bO', // STON
        },
      });

      widget.mount(document.querySelector("#omniston-widget-container"));
    </script>
  </body>
</html>
```

**Option B — npm (React, integrated TON Connect UI)**

```tsx
import { useEffect, useRef } from 'react';
import { TonConnectUIProvider, TonConnectButton, useTonConnectUI } from '@tonconnect/ui-react';
import omnistonWidgetLoader, { type OmnistonWidget } from '@ston-fi/omniston-widget-loader';

function SwapWidget() {
  const [tonconnect] = useTonConnectUI();
  const containerRef = useRef<HTMLDivElement | null>(null);
  const widgetRef = useRef<OmnistonWidget | null>(null);

  useEffect(() => {
    let isMounted = true;

    omnistonWidgetLoader.load().then((OmnistonWidgetConstructor) => {
      if (!isMounted || !containerRef.current || !tonconnect) return;

      widgetRef.current = new OmnistonWidgetConstructor({
        tonconnect: {
          type: 'integrated',
          instance: tonconnect,
        },
        widget: {
          defaultBidAsset: 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', // TON
          defaultAskAsset: 'EQA2kCVNwVsil2EM2mB0SkXytxCqQjS4mttjDpnXmwG9T6bO', // STON
        },
      });

      widgetRef.current.mount(containerRef.current);
    });

    return () => {
      isMounted = false;
      widgetRef.current?.unmount();
      widgetRef.current = null;
    };
  }, [tonconnect]);

  return (
    <div
      style={{
        minHeight: '100vh',
        padding: '2rem',
        display: 'flex',
        flexDirection: 'column',
        gap: 16,
        alignItems: 'center',
        width: '100%',
      }}
    >
      <h1 style={{ textAlign: 'center', marginBottom: '1rem' }}>STON.fi (swap) Widget</h1>
      <div style={{ textAlign: 'center', marginBottom: '1.5rem' }}>
        <TonConnectButton />
      </div>
      <div
        ref={containerRef}
        style={{ width: '100%', maxWidth: 500, margin: '0 auto' }}
      />
    </div>
  );
}

export default function App() {
  return (
    <TonConnectUIProvider
      // see https://docs.ton.org/ecosystem/ton-connect/manifest
      manifestUrl="https://[myapp.com]/tonconnect-manifest.json"
    >
      <SwapWidget />
    </TonConnectUIProvider>
  );
}
```

See [Full Guide](https://docs.ston.fi/developer-section/widget/widget) for full CDN, React, and vanilla examples.

## Visual Widget Constructor

**Quick customization without code:** Use our visual widget constructor at [widget.ston.fi/constructor](https://widget.ston.fi/constructor) to configure your widget interactively.

<figure><img src="https://1159777691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCJ1ZKietYw2GrKAuOqA8%2Fuploads%2Fgit-blob-3dcb833dbe9b1811a146ba8f582c97a4f1b65f7b%2Fwidget_dark.png?alt=media" alt=""><figcaption></figcaption></figure>

The constructor provides:

* **Theme customization** — Start from light or dark and adapt to your brand
* **Asset list control** — Use default assets, add your own, or replace the list entirely
* **Referral fees** — Configure your referrer address and fee
* **Code export** — Copy ready-to-use CSS and JS snippets

Prefer doing this in code? See **Configure in code** below.

## Configure in code

All options from the visual constructor map directly to the `OmnistonWidget` configuration object. You control four main areas:

### 1. Referral fees

Set both `referrerAddress` and `referrerFeeBps` to earn 0.01%–1% (1–100 bps) on every swap. See the [Referral Fees guide](https://docs.ston.fi/developer-section/omniston/referral-fees) for payout details and best practices.

### 2. Asset list

The widget ships with sensible defaults and only requires your TON Connect manifest URL. For optional asset overrides and the complete configuration table, see [Configuration options](https://docs.ston.fi/developer-section/widget#configuration-options).

### 3. Theme (CSS variables)

Override CSS custom properties on the container you pass to `widget.mount(...)` to align the widget with your brand. Refer to [Customize widget styles](https://docs.ston.fi/developer-section/widget#customize-widget-styles) for the full variable list and styling examples.

### 4. TON Connect modes

* **`standalone`** – Widget manages TON Connect with only your manifest URL.
* **`integrated`** – Reuse an existing TON Connect instance from your app.

For wiring examples, warnings about multiple instances, and full configuration, see the TON Connect section in [Full Guide](https://docs.ston.fi/developer-section/widget/widget).

### Advanced capabilities

CDN distribution is also available as a zero-build option; see the [CDN distribution section](https://docs.ston.fi/developer-section/widget#cdn-distribution-no-bundler-required) in [Advanced: lifecycle events and manual mount/unmount](https://docs.ston.fi/developer-section/widget#advanced-lifecycle-events-and-manual-mount-unmount) for implementation details.

## Next Steps

* [Full Guide](https://docs.ston.fi/developer-section/widget/widget) – Comprehensive installation, configuration, CDN usage, TON Connect wiring, referral fees, theming, and lifecycle events.
