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

# Widget events

> Custom events from vulcx-swap: quote-update, swap-initiated, swap-complete, swap-error, connect-wallet.

The `<vulcx-swap>` element dispatches custom events at key points in the swap lifecycle. All events have `bubbles: true` and `composed: true`, so they cross the shadow DOM boundary.

***

## Event Reference

| Event            | Fired when                                        | `detail` type                                               |
| ---------------- | ------------------------------------------------- | ----------------------------------------------------------- |
| `quote-update`   | A new quote is fetched                            | `QuoteResponse`                                             |
| `swap-initiated` | User clicks "Swap" and the request starts         | `{ inputMint: string, outputMint: string, amount: string }` |
| `swap-complete`  | Swap transaction is built successfully            | `SwapResponse`                                              |
| `swap-error`     | Swap request fails                                | `{ error: string }`                                         |
| `connect-wallet` | User clicks the button without a wallet connected | `{}`                                                        |

***

## `quote-update`

Fired every time a new quote loads (after the 400ms debounce).

```typescript theme={"theme":"github-dark"}
interface QuoteUpdateDetail {
  inputMint: string;
  outputMint: string;
  amountIn: string;
  amountOut: string;
  priceImpactBps: number;
  priceImpactPercent: string;
  priceImpactSeverity: "none" | "low" | "moderate" | "high" | "extreme";
  priceImpactWarning: string;
  feeBps: number;
  routes: Array<{
    poolAddress: string;
    poolType: string;
    percent: number;
    inputMint: string;
    outputMint: string;
  }>;
  routePath: string[];
  hopCount: number;
  otherAmountThreshold: string;
}
```

```javascript theme={"theme":"github-dark"}
widget.addEventListener("quote-update", (e) => {
  console.log("Output:", e.detail.amountOut);
  console.log("Impact:", e.detail.priceImpactPercent);
  console.log("Route:", e.detail.routes.map(r => r.poolType).join(" → "));
});
```

***

## `swap-initiated`

Fired when the user clicks "Swap" and the SDK request begins. Use this for analytics or loading states.

```typescript theme={"theme":"github-dark"}
interface SwapInitiatedDetail {
  inputMint: string;
  outputMint: string;
  amount: string;
}
```

```javascript theme={"theme":"github-dark"}
widget.addEventListener("swap-initiated", (e) => {
  console.log("Swapping", e.detail.amount, "from", e.detail.inputMint);
});
```

***

## `swap-complete`

Fired when the swap transaction is built successfully. The `detail` contains the full `SwapResponse` including the base64 transaction.

```typescript theme={"theme":"github-dark"}
interface SwapCompleteDetail {
  transaction: string;
  lastValidBlockHeight: number;
  amountIn: string;
  amountOut: string;
  minAmountOut?: string;
  feeAmount: string;
  route: string[];
  hopCount: number;
  pools: string[];
}
```

```javascript theme={"theme":"github-dark"}
widget.addEventListener("swap-complete", (e) => {
  console.log("Swap built:", e.detail.amountIn, "→", e.detail.amountOut);
  // Sign and submit e.detail.transaction with your wallet
});
```

***

## `swap-error`

Fired when the swap request fails.

```typescript theme={"theme":"github-dark"}
interface SwapErrorDetail {
  error: string;
}
```

```javascript theme={"theme":"github-dark"}
widget.addEventListener("swap-error", (e) => {
  console.error("Swap failed:", e.detail.error);
});
```

***

## `connect-wallet`

Fired when the user clicks the primary button but no wallet is connected. Use this to trigger your wallet adapter's connect flow.

```typescript theme={"theme":"github-dark"}
interface ConnectWalletDetail {} // empty
```

```javascript theme={"theme":"github-dark"}
widget.addEventListener("connect-wallet", async () => {
  const wallet = await connectWallet(); // your wallet adapter
  widget.setWallet(wallet.publicKey.toString());
});
```

See [Wallet Integration](./wallet-integration.md) for full patterns.

***

## Listening in Frameworks

### React

```tsx theme={"theme":"github-dark"}
import { useEffect, useRef } from "react";
import "@vulcx/widget";

function SwapWidget() {
  const ref = useRef<HTMLElement>(null);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    const onQuote = (e: Event) => {
      console.log("Quote:", (e as CustomEvent).detail);
    };
    el.addEventListener("quote-update", onQuote);
    return () => el.removeEventListener("quote-update", onQuote);
  }, []);

  return <vulcx-swap ref={ref} api-key="vulcx_..." />;
}
```

### Vue

```vue theme={"theme":"github-dark"}
<template>
  <vulcx-swap
    api-key="vulcx_..."
    @quote-update="onQuote"
    @swap-complete="onSwap"
    @connect-wallet="onConnect"
  />
</template>

<script setup>
import "@vulcx/widget";

function onQuote(e) { console.log(e.detail); }
function onSwap(e) { console.log(e.detail); }
function onConnect() { /* trigger wallet connect */ }
</script>
```


## Related topics

- [Widget wallet integration](/widget/wallet-integration.md)
- [Widget quickstart](/widget/quickstart.md)
- [Widget theming](/widget/theming.md)
- [Widget attributes](/widget/attributes.md)
- [Widget examples](/widget/examples.md)
