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

# How to Embed a Swap Widget in Your App

> Add a full-featured token swap to your app with one script tag. No RPC, no wallet infrastructure, no UI to build.

## TL;DR

Jupiter Plugin gives you the same swap experience as [jup.ag](https://jup.ag), embedded directly in your app. One script tag, one function call. No RPC node, no wallet adapter code, no UI to build. Powered by [Ultra](https://developers.jup.ag/docs/ultra/index), which handles routing, slippage, MEV protection, and transaction sending.

> [!TIP]
>
> **Video walkthrough + source code:** Watch the [video walkthrough](https://x.com/JupDevRel/status/2033528378134028756) and grab the [demo app source code](https://github.com/jup-ag/api-examples/tree/main/apps/plugin-community-site) on GitHub.

***

## Prerequisites

No API key or RPC node required. Jupiter Plugin handles all infrastructure.

For framework-based apps, you need **Node.js and npm** installed from [nodejs.org](https://nodejs.org). For plain HTML, you just need a browser.

***

## Quick start

The simplest way to add a swap widget: a single HTML file:

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <script src="https://plugin.jup.ag/plugin-v1.js" data-preload defer></script>
</head>
<body>
  <h1>My App</h1>
  <div id="jupiter-plugin"></div>
  <script>
    window.onload = function() {
      window.Jupiter.init({
        displayMode: "integrated",
        integratedTargetId: "jupiter-plugin",
      });
    };
  </script>
</body>
</html>
```

Save this as `swap.html`, serve it locally, and open it in your browser:

```bash theme={null}
npx http-server -o /swap.html
```

## Try it yourself

Not ready to write code? The [Plugin Playground](https://plugin.jup.ag/) lets you experience the full swap widget live in your browser. Switch display modes, set token defaults, tweak colours, and copy the generated code when you're ready to integrate.

[![Plugin Playground](https://mintcdn.com/jupiter/mrenEfoqnubhOTHf/static/images/plugin-playground.png?fit=max\&auto=format\&n=mrenEfoqnubhOTHf\&q=85\&s=ef4ff667cff780774d3da617a9022a3b)](https://plugin.jup.ag/)

***

## When you need this

You want to add swap functionality to your app or website without building any of it yourself:

* **App with swap:** Your app needs token swaps but you don't want to build the UI, handle transactions, or run an RPC node.
* **Community token site:** Let your community buy your token directly on your website by locking the output mint with `fixedMint`.
* **Quick swap access:** Add a floating widget to any page for convenient swapping.

Common searches that lead here:

* "embed swap widget solana"
* "add token swap to my website"
* "jupiter plugin integration"
* "buy token widget solana"
* "solana swap widget no backend"
* "drop-in swap component solana"
* "add jupiter swap to react app"
* "token swap widget html"

***

## Why Jupiter Plugin

Building a swap interface from scratch means:

* Running an RPC node
* Integrating a wallet adapter
* Building the swap UI
* Handling quoting, routing, slippage, and MEV protection
* Managing transaction errors and retries

Jupiter Plugin handles all of this. You get the full [jup.ag](https://jup.ag) swap experience as a drop-in component:

* **No RPC:** Powered by Ultra, which handles all transaction sending.
* **No wallet code:** Plugin provides wallet connection out of the box (users connect their existing browser wallet like Phantom or Backpack).
* **No UI to build:** Complete swap interface with token search, price display, and transaction status.
* **No error handling:** Plugin manages slippage, retries, and transaction failures.

***

## Code examples

Add the plugin script to your page, then call `window.Jupiter.init()`. Here's a complete working example for each framework:

```html HTML theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Jupiter Plugin Demo</title>
    <script src="https://plugin.jup.ag/plugin-v1.js" data-preload defer></script>
</head>
<body>
    <h1>Jupiter Plugin Demo</h1>
    <div id="jupiter-plugin"></div>

    <script>
        window.onload = function() {
            window.Jupiter.init({
                displayMode: "integrated",
                integratedTargetId: "jupiter-plugin",
            });
        };
    </script>
</body>
</html>
```

```tsx React theme={null}
import { useEffect } from "react";

// Add to public/index.html <head>:
// <script src="https://plugin.jup.ag/plugin-v1.js" data-preload defer></script>

export default function App() {
  useEffect(() => {
    window.Jupiter.init({
      displayMode: "integrated",
      integratedTargetId: "jupiter-plugin",
    });
  }, []);

  return (
    <div>
      <h1>Jupiter Plugin Demo</h1>
      <div id="jupiter-plugin" />
    </div>
  );
}
```

```tsx Next.js theme={null}
"use client";
import { useEffect } from "react";
import Script from "next/script";

export default function SwapPage() {
  return (
    <>
      <Script
        src="https://plugin.jup.ag/plugin-v1.js"
        data-preload
        strategy="afterInteractive"
        onReady={() => {
          window.Jupiter.init({
            displayMode: "integrated",
            integratedTargetId: "jupiter-plugin",
          });
        }}
      />
      <h1>Jupiter Plugin Demo</h1>
      <div id="jupiter-plugin" />
    </>
  );
}
```

For a full step-by-step walkthrough with TypeScript support and project setup:

> [card] [Next.js](https://developers.jup.ag/docs/tool-kits/plugin/nextjs-app-example.md)

> [card] [React](https://developers.jup.ag/docs/tool-kits/plugin/react-app-example.md)

> [card] [HTML](https://developers.jup.ag/docs/tool-kits/plugin/html-app-example.md)

***

## Configuration

### Display modes

Jupiter Plugin offers three display modes:

| Mode | Description | Use case |
| - | - | - |
| `integrated` | Embeds directly in your page layout | Dedicated swap page or section |
| `widget` | Floating button that expands to a swap form | Quick access on any page |
| `modal` | Popup overlay triggered by your app | On-demand swap without layout changes |

```javascript theme={null}
// Integrated: renders inside a target element
window.Jupiter.init({
  displayMode: "integrated",
  integratedTargetId: "jupiter-plugin", // ID of your container div
});

// Widget: floating in a corner
window.Jupiter.init({
  displayMode: "widget",
  widgetStyle: {
    position: "bottom-right", // bottom-left, bottom-right, top-left, top-right
    size: "default",          // sm, default
  },
});

// Modal: popup overlay
window.Jupiter.init({
  displayMode: "modal",
});
```

### Form props

Pre-configure the swap form with `formProps`:

```javascript theme={null}
window.Jupiter.init({
  displayMode: "integrated",
  integratedTargetId: "jupiter-plugin",
  formProps: {
    initialInputMint: "So11111111111111111111111111111111111111112",  // SOL
    initialOutputMint: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", // JUP
    initialAmount: "1",
    fixedMint: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", // Lock output to JUP
    fixedAmount: false,
  },
});
```

| Prop | Type | Description |
| - | - | - |
| `initialInputMint` | `string` | Pre-select the input token (mint address) |
| `initialOutputMint` | `string` | Pre-select the output token (mint address) |
| `initialAmount` | `string` | Pre-fill the swap amount |
| `fixedMint` | `string` | Lock one side of the swap to a specific token |
| `fixedAmount` | `boolean` | Prevent users from changing the amount |
| `swapMode` | `string` | `"ExactIn"`, `"ExactOut"`, or `"ExactInOrOut"` (default) |

**Community token site example:** Let your community buy your token directly:

```javascript theme={null}
window.Jupiter.init({
  displayMode: "integrated",
  integratedTargetId: "jupiter-plugin",
  formProps: {
    initialOutputMint: "YOUR_TOKEN_MINT_ADDRESS",
    fixedMint: "YOUR_TOKEN_MINT_ADDRESS",
  },
});
```

### Wallet passthrough

If your app already has a wallet provider (e.g. via `@solana/wallet-adapter`), you can pass the wallet state through to Plugin instead of having users connect twice:

```javascript theme={null}
window.Jupiter.init({
  displayMode: "integrated",
  integratedTargetId: "jupiter-plugin",
  enableWalletPassthrough: true,
});

// Sync wallet state when it changes
window.Jupiter.syncProps({
  passthroughWalletContextState: walletContextState,
});
```

If you don't enable passthrough, Plugin provides its own wallet connection. Users connect their browser wallet (Phantom, Backpack, etc.) directly through the widget.

### Referral fees

Earn fees on swaps through the [Jupiter Referral Program](https://developers.jup.ag/docs/tool-kits/referral-program.md):

```javascript theme={null}
window.Jupiter.init({
  displayMode: "widget",
  formProps: {
    referralAccount: "YOUR_REFERRAL_ACCOUNT",
    referralFee: 50, // Basis points (50 = 0.5%)
  },
});
```

### Branding

Add your logo and name to the Plugin:

```javascript theme={null}
window.Jupiter.init({
  displayMode: "widget",
  branding: {
    logoUri: "https://your-app.com/logo.png",
    name: "Your App",
  },
});
```

### Colour theme

Customise colours via CSS variables in your global stylesheet:

```css theme={null}
:root {
  --jupiter-plugin-primary: 199, 242, 132;
  --jupiter-plugin-background: 0, 0, 0;
  --jupiter-plugin-primaryText: 232, 249, 255;
  --jupiter-plugin-warning: 251, 191, 36;
  --jupiter-plugin-interactive: 33, 42, 54;
  --jupiter-plugin-module: 16, 23, 31;
}
```

### Event handling

Track swap results in your app:

```javascript theme={null}
window.Jupiter.init({
  displayMode: "widget",
  onSuccess: ({ txid, swapResult, quoteResponseMeta }) => {
    console.log("Swap successful:", txid);
  },
  onSwapError: ({ error, quoteResponseMeta }) => {
    console.error("Swap failed:", error);
  },
});
```

***

## Common questions

> [accordion] Do I need an API key or RPC node?
>
> No. Jupiter Plugin handles all infrastructure through Ultra. No API key, no RPC node, no backend required.

> [accordion] Can I lock the swap to a specific token?
>
> Yes. Use `formProps.fixedMint` to lock one side of the swap to a specific token mint address. Combine with `fixedAmount` to also lock the amount (useful for payment flows).

> [accordion] How do users connect their wallet?
>
> Plugin provides wallet connection out of the box. Users click the connect button in the widget and select their browser wallet (Phantom, Backpack, etc.). If your app already has a wallet provider, use `enableWalletPassthrough` to avoid a double connection.

> [accordion] How do I test before deploying?
>
> Use the [Plugin Playground](https://plugin.jup.ag/) to experiment with display modes, form props, and colour themes. It generates the configuration code for you.

> [accordion] Why does integrated mode have no height?
>
> The integrated mode container needs a fixed height. Set it on your target div:
>
> ```html theme={null}
> <div id="jupiter-plugin" style="height: 600px;"></div>
> ```

***

## Next steps

* **[Plugin Playground](https://plugin.jup.ag/):** Experiment with configuration and get code snippets.
* **[Customisation Reference](https://developers.jup.ag/docs/tool-kits/plugin/customization.md):** Full configuration options and TypeScript types.
* **[Framework Walkthroughs](https://developers.jup.ag/docs/tool-kits/plugin/nextjs-app-example.md):** Step-by-step guides for Next.js, React, and HTML.
* **[Referral Program](https://developers.jup.ag/docs/tool-kits/referral-program.md):** Earn fees on swaps through your integration.
* **[Jupiter Dev Notifications](https://t.me/jup_dev):** Plugin updates and announcements.


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