> For the complete documentation index, see [llms.txt](https://docs.swapkit.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.swapkit.dev/swapkit-widget/configuring-in-code.md).

# Configuring in code

Most partners should configure these settings visually in [Widget Studio](/swapkit-widget/widget-studio.md) and copy the generated snippet, rather than writing attributes by hand. The reference tables here are for when you need to understand or fine-tune a value the snippet produced, maybe to adapt the behaviour to the specific user visiting the site or to the content of the page they are viewing.

Every setting is exposed in two places, and the two map one to one:

* **Web component:** kebab-case HTML attributes on `<swapkit-widget>` (e.g. `input-asset`).
* **React:** camelCase props on `<SwapKitWidget />` (e.g. `inputAsset`).

You can set them statically in your embed, or set them programmatically so the widget reflects the current context. The full lists are in [Full attribute reference](#full-attribute-reference-web-component) and [Full props reference](#full-props-reference-react).

### Updating settings at runtime

This is the main reason to configure in code rather than from a static snippet: you can change the widget to match the user or the page they are on.

{% tabs %}
{% tab title="HTML" %}
Registered attributes are observed, so setting an attribute with JavaScript re-renders the widget in place. For example, on a token page, preselect that token as the receive asset and narrow the wallet list:

```js
const widget = document.querySelector("swapkit-widget");
widget.setAttribute("output-asset", "ETH.USDT-0xdAC17F958D2EE523A2206206994597C13D831EC7");
widget.setAttribute("wallets", "METAMASK,WALLETCONNECT");
```

{% endtab %}

{% tab title="React" %}
Props are reactive, so drive them from state, the route, or the user's session and the widget updates when they change:

```tsx
function PageWidget({ tokenForThisPage }: { tokenForThisPage: string }) {
  const [theme, setTheme] = useState<SwapKitThemeTokens>(darkTheme);

  return (
    <SwapKitWidget
      widgetId={process.env.NEXT_PUBLIC_SWAPKIT_WIDGET_ID!}
      widgetKey={process.env.SWAPKIT_WIDGET_KEY!}
      outputAsset={tokenForThisPage}
      theme={theme}
    />
  );
}
```

{% endtab %}
{% endtabs %}

Common things to drive dynamically:

* **Default assets** to match the product, token, or pair the page is about.
* **Wallet list** to suit the user's region or device.
* **Theme** to follow a light/dark toggle on the host page.

Caveats:

* Only attributes in the attribute reference are observed; setting an unrecognised attribute has no effect. Every documented attribute (including all theme tokens) re-renders on change.
* Do not swap auth values (`widget-id` / `widget-key` / `api-key`) at runtime in normal use. Set them once.

***

### Authentication

The widget supports two mutually exclusive authentication modes.

| Mode                          | Web component              | React props              | Notes                                                                            |
| ----------------------------- | -------------------------- | ------------------------ | -------------------------------------------------------------------------------- |
| **Widget auth** (recommended) | `widget-id` + `widget-key` | `widgetId` + `widgetKey` | Recommended for all browser embeds. Both values are required together.           |
| **API key**                   | `api-key`                  | `apiKey`                 | Supported, but exposes an API key client-side. Use only in trusted environments. |

Behavior to be aware of:

* **Both widget values are required.** If only one of `widget-id` / `widget-key` is present, the widget logs a warning and API requests fail authentication.
* **API key takes precedence.** If an API key is present alongside a widget pair, the widget uses the API key and clears the widget auth. For public embeds, set only the widget pair.
* **Widget auth is domain-bound.** Keys are issued for an exact domain (`example.com`) or a wildcard (`*.example.com`, which also covers the base domain). The widget only authenticates on the registered domain.

To create a widget key, add a domain, or rotate the key, see [Creating your widget keys](/swapkit-widget/creating-your-widget-keys.md).

***

### Theming

The widget is themed with a set of tokens. Set them with the `theme` prop (React) or individual `color-*` / `border-radius` / `font-family` attributes (web component).

Color values are HSL channels without the `hsl()` wrapper, for example `155 86% 62%`, not `hsl(155 86% 62%)`. Use the form `"H S% L%"` or `"H S% L% / A"` (the `/ A` adds an alpha channel). The widget composes these into `hsl(...)` internally.

#### Color tokens

All of these color tokens are observed at runtime. Every one except Accent Text is also exposed in Studio's Design tab and emitted in the generated snippet when changed from its default.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="118">Token</th><th>Web component attribute</th><th width="160">React theme key</th><th>Default</th><th>Affects</th></tr></thead><tbody><tr><td>Background</td><td><code>color-primary</code></td><td><code>background</code></td><td><code>140 6% 8%</code></td><td>Main widget background</td></tr><tr><td>Surface</td><td><code>color-secondary</code></td><td><code>surface</code></td><td><code>120 3% 13%</code></td><td>Elevated surfaces (cards, dialogs)</td></tr><tr><td>Accent</td><td><code>color-accent</code></td><td><code>accent</code></td><td><code>140 87% 79%</code></td><td>Accent color (steppers, highlights)</td></tr><tr><td>Accent Text</td><td><code>color-accent-foreground</code></td><td><code>accentForeground</code></td><td><code>140 6% 8%</code></td><td>Text on accent backgrounds</td></tr><tr><td>Button</td><td><code>color-primary-button</code></td><td><code>primaryButton</code></td><td><code>0 0% 100% / 0.92</code></td><td>Primary button background</td></tr><tr><td>Button Text</td><td><code>color-primary-button-foreground</code></td><td><code>primaryButtonForeground</code></td><td><code>140 6% 8%</code></td><td>Primary button text</td></tr><tr><td>Text</td><td><code>color-text</code></td><td><code>text</code></td><td><code>0 0% 100% / 0.92</code></td><td>Main text</td></tr><tr><td>Muted Text</td><td><code>color-muted-foreground</code></td><td><code>mutedForeground</code></td><td><code>0 0% 100% / 0.64</code></td><td>Secondary text</td></tr><tr><td>Border</td><td><code>color-border</code></td><td><code>border</code></td><td><code>0 0% 100% / 0.12</code></td><td>Borders</td></tr><tr><td>Hover</td><td><code>color-bg-hover</code></td><td><code>hover</code></td><td><code>0 0% 100% / 0.08</code></td><td>Hover state</td></tr><tr><td>Active</td><td><code>color-bg-active</code></td><td><code>active</code></td><td><code>0 0% 100% / 0.12</code></td><td>Active / pressed state</td></tr><tr><td>Overlay</td><td><code>color-bg-overlay</code></td><td><code>overlay</code></td><td><code>0 0% 0% / 0.8</code></td><td>Modal backdrop overlay</td></tr></tbody></table>

#### Shape tokens

<table><thead><tr><th width="126">Token</th><th width="143">Web component attribute</th><th width="115">React theme key</th><th width="130">Default</th><th>Affects</th></tr></thead><tbody><tr><td>Border radius</td><td><code>border-radius</code></td><td><code>radius</code></td><td><code>0.5rem</code></td><td>Corner rounding (CSS length, not HSL)</td></tr><tr><td>Font family</td><td><code>font-family</code></td><td><code>fontFamily</code></td><td>system stack</td><td>Font applied to the widget root</td></tr></tbody></table>

Example:

{% tabs %}
{% tab title="HTML" %}

```html
<swapkit-widget
  widget-id="YOUR_WIDGET_ID"
  widget-key="YOUR_WIDGET_KEY"
  color-primary="220 18% 8%"
  color-secondary="220 14% 13%"
  color-accent="155 86% 62%"
  color-primary-button="155 86% 62%"
  color-primary-button-foreground="220 18% 8%"
></swapkit-widget>
```

{% endtab %}

{% tab title="React" %}
Use the `theme` prop:

```tsx
<SwapKitWidget
  widgetId="YOUR_WIDGET_ID"
  widgetKey="YOUR_WIDGET_KEY"
  theme={{
    background: "220 18% 8%",
    surface: "220 14% 13%",
    accent: "155 86% 62%",
    primaryButton: "155 86% 62%",
    primaryButtonForeground: "220 18% 8%",
    radius: "0.75rem",
  }}
/>
```

{% endtab %}
{% endtabs %}

***

### Default assets

You can set which assets the widget loads with. Assets use the format `CHAIN.SYMBOL` (e.g. `BTC.BTC`) or `CHAIN.SYMBOL-CONTRACT` for tokens (e.g. `ETH.USDT-0xdAC17F958D2EE523A2206206994597C13D831EC7`).

<table><thead><tr><th width="135"></th><th width="137">Web component</th><th width="124">React prop</th><th>Default</th></tr></thead><tbody><tr><td>Pay asset</td><td><code>input-asset</code></td><td><code>inputAsset</code></td><td><code>BTC.BTC</code></td></tr><tr><td>Receive asset</td><td><code>output-asset</code></td><td><code>outputAsset</code></td><td><code>ETH.USDT-0xdAC17F958D2EE523A2206206994597C13D831EC7</code></td></tr></tbody></table>

These are good candidates for runtime updates: set `output-asset` (or `outputAsset`) to whatever token the current page is about.

### Chain selection

By default the widget operates on every API-supported chain. You can restrict the set with an allowlist or blocklist. Dropping a chain hides it from the asset selector and auto-disables any wallet whose only chains were removed (for example, removing `XRP` also removes Xaman).

{% tabs %}
{% tab title="HTML" %}
There are three attributes, each taking a comma-separated list of chains. Set only one of them. (If you set more than one, the widget uses the first it finds, in the order `chains`, then `chains-include`, then `chains-exclude`.)

Show only the chains you list:

```html
<swapkit-widget chains="BTC,ETH,SOL" ...></swapkit-widget>
```

`chains-include` is an alternative way to write that same allowlist:

```html
<swapkit-widget chains-include="BTC,ETH,SOL" ...></swapkit-widget>
```

Or start from every chain and remove a few, with `chains-exclude`:

```html
<swapkit-widget chains-exclude="TRON,DASH" ...></swapkit-widget>
```

To operate on every chain (the default), either omit these attributes or set `chains="all"`.
{% endtab %}

{% tab title="React" %}
Pass the `chains` prop:

```tsx
type ChainConfig =
  | Chain[]                  // explicit list
  | "all"                    // every API-supported chain (default)
  | { include: Chain[] }     // allowlist
  | { exclude: Chain[] };    // blocklist
```

{% endtab %}
{% endtabs %}

#### Supported chains

Chain identifiers are the SwapKit chain keys. Unlike `wallets`, they are case-sensitive on the web component attribute, so pass them exactly as listed. Supported chains:

`BTC`, `ETH`, `TRON`, `BSC`, `SOL`, `ZEC`, `XRP`, `ARB`, `BASE`, `OP`, `POL`, `AVAX`, `ADA`, `GAIA`, `SUI`, `NEAR`, `DOGE`, `LTC`, `BCH`, `DASH`, `GNO`, `XLAYER`, `THOR`, `MAYA`, `BERA`, `MONAD`, `XRD`, `KUJI`, `TON`, and `STARKNET`.

***

### Wallet selection

By default the widget shows every available wallet. You can restrict the list with an allowlist or blocklist.

**Web component**: use one of `wallets`, `wallets-include`, or `wallets-exclude` (mutually exclusive; precedence is `wallets`, then `include`, then `exclude`):

```html
<swapkit-widget wallets="METAMASK,LEDGER,WALLETCONNECT" ...></swapkit-widget>
```

**React**: pass the `wallets` prop:

```ts
type WalletConfig =
  | WalletOption[]                  // explicit list
  | "all"                           // every available wallet (default)
  | "none"                          // disable wallet connection
  | { include: WalletOption[] }     // allowlist
  | { exclude: WalletOption[] };    // blocklist
```

Common `WalletOption` values: `METAMASK`, `LEDGER`, `TREZOR`, `KEYSTORE`, `WALLETCONNECT`, `PHANTOM`, `COINBASE_WEB`, `COINBASE_MOBILE`, `XAMAN`, `RADIX_WALLET`, `PASSKEYS`. But there are more than 20 different wallets.

The visible wallet list is also filtered automatically at runtime:

* **Mobile filtering.** Hardware wallets and desktop-only extensions are hidden on mobile user agents. Wallets with a mobile path (MetaMask, Coinbase, Phantom) stay visible because they may load inside the wallet's in-app browser.
* **Experimental wallets** (currently `KEEPKEY` and `VULTISIG`) are hidden in production and only surface when Developer Mode is enabled.
* **Direct-signing support.** A wallet is only shown if it supports at least one widget-supported chain.

***

### Wallet-provider credentials

Some wallet providers require additional credentials before they can connect. Fill the corresponding fields in Studio's Settings tab and they are serialized automatically into the generated snippet's `config` JSON attribute (empty fields are omitted). You rarely need to write this JSON by hand.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="174">Wallet / integration</th><th>Required fields</th><th>Recommended fields</th><th>Where to get it</th></tr></thead><tbody><tr><td><strong>WalletConnect</strong></td><td><code>apiKeys.walletConnectProjectId</code></td><td>None</td><td>https://cloud.reown.com</td></tr><tr><td><strong>Xaman (XRPL)</strong></td><td><code>apiKeys.xaman</code></td><td>None</td><td>https://apps.xumm.dev</td></tr><tr><td><strong>Radix Wallet</strong></td><td><code>integrations.radix.dAppDefinitionAddress</code>, <code>applicationName</code>, <code>applicationVersion</code></td><td>Network ID / Name, Dashboard Base URL (have defaults)</td><td>https://console.radixdlt.com</td></tr><tr><td><strong>KeepKey</strong></td><td><code>integrations.keepKey.basePath</code>, <code>url</code></td><td><code>name</code>, <code>imageUrl</code></td><td>https://docs.keepkey.com</td></tr><tr><td><strong>Passkeys</strong></td><td><code>apiKeys.passkeys</code></td><td>None</td><td>Issued by SwapKit / dashboard</td></tr><tr><td><strong>Trezor</strong></td><td>None hard-required</td><td><code>integrations.trezor.email</code>, <code>appUrl</code></td><td>https://docs.trezor.io/trezor-suite/packages/connect</td></tr><tr><td><strong>Coinbase Wallet</strong></td><td>None hard-required</td><td><code>integrations.coinbase.appName</code>, <code>appLogoUrl</code></td><td>https://docs.cdp.coinbase.com/wallet-sdk/docs/installing</td></tr><tr><td><strong>NEAR Wallet Selector</strong></td><td><code>integrations.nearWalletSelector.contractId</code></td><td>None</td><td>Your NEAR contract/account setup</td></tr></tbody></table>

#### The `config` payload

The full shape accepted by the `config` attribute:

```json
{
  "apiKeys": {
    "walletConnectProjectId": "...",
    "xaman": "...",
    "passkeys": "...",
    "keepKey": "..."
  },
  "integrations": {
    "coinbase": { "appName": "...", "appLogoUrl": "https://..." },
    "nearWalletSelector": { "contractId": "..." },
    "trezor": { "email": "support@example.com", "appUrl": "https://example.com" },
    "keepKey": { "name": "...", "imageUrl": "https://...", "basePath": "...", "url": "..." },
    "radix": {
      "dAppDefinitionAddress": "...",
      "applicationName": "...",
      "applicationVersion": "...",
      "network": { "networkId": 1, "networkName": "mainnet", "dashboardBase": "https://dashboard.radixdlt.com" }
    }
  }
}
```

To use it, for the different integration options:

***

### Developer settings

These control which environment the widget talks to. Production embeds should omit all of them.

<table><thead><tr><th width="192">Setting</th><th width="147">Web component</th><th width="122">React</th><th>Notes</th></tr></thead><tbody><tr><td>API endpoint override</td><td><code>api-base-url</code></td><td><code>apiBaseUrl</code></td><td>Override the SwapKit API base URL (default <code>https://api.swapkit.dev</code>). Use only for staging/dev.</td></tr><tr><td>Developer Mode</td><td><code>develop-mode</code></td><td>None</td><td>Boolean attribute. Surfaces experimental wallets and dev behavior, and switches Studio's generated CDN to <code>cdn-dev.swapkit.dev</code>. Omit in production.</td></tr><tr><td>Dev API URL</td><td><code>dev-api-url</code></td><td>None</td><td>API URL used when Developer Mode is enabled.</td></tr></tbody></table>

A development embed looks like this (note the dev CDN):

```html
<script type="module" src="https://cdn-dev.swapkit.dev/widget/latest/swapkit-widget.js"></script>

<swapkit-widget
  widget-id="YOUR_DEV_WIDGET_ID"
  widget-key="YOUR_DEV_WIDGET_KEY"
  develop-mode
></swapkit-widget>
```

***

### URL sync

Set `syncUrl` (React) to mirror the selected assets and amount into the page's query string. The parameters are `input_asset`, `output_asset`, and `amount` (for example `?input_asset=BTC.BTC&output_asset=ETH.ETH&amount=0.1`). This is a React-only prop; there is no web component attribute for it. Most partner embeds leave it off (default `false`). It is useful if you want the current selection to survive a reload or be shareable as a link.

***

### Full attribute reference (web component)

<table><thead><tr><th width="165">Attribute</th><th width="167">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>widget-id</code></td><td>string</td><td>Widget ID from the dashboard. Pair with <code>widget-key</code>.</td></tr><tr><td><code>widget-key</code></td><td>string</td><td>Widget Key from the dashboard. Pair with <code>widget-id</code>.</td></tr><tr><td><code>api-key</code></td><td>string</td><td>Alternative auth mode. Takes precedence over widget auth.</td></tr><tr><td><code>api-base-url</code></td><td>URL</td><td>Override the SwapKit API base URL.</td></tr><tr><td><code>develop-mode</code></td><td>boolean</td><td>Enable development behavior. Presence (or <code>"true"</code>) is treated as enabled.</td></tr><tr><td><code>dev-api-url</code></td><td>URL</td><td>Development API URL used when <code>develop-mode</code> is set.</td></tr><tr><td><code>input-asset</code></td><td>asset string</td><td>Initial pay asset. Default <code>BTC.BTC</code>.</td></tr><tr><td><code>output-asset</code></td><td>asset string</td><td>Initial receive asset. Default Ethereum USDT.</td></tr><tr><td><code>wallets</code></td><td><code>all</code>, <code>none</code>, or CSV</td><td>Restrict which wallet options are shown.</td></tr><tr><td><code>wallets-include</code></td><td>CSV</td><td>Explicit allowlist.</td></tr><tr><td><code>wallets-exclude</code></td><td>CSV</td><td>Blocklist, showing all wallets except these.</td></tr><tr><td><code>chains</code></td><td><code>all</code> or CSV</td><td>Restrict which chains the widget operates on.</td></tr><tr><td><code>chains-include</code></td><td>CSV</td><td>Explicit chain allowlist.</td></tr><tr><td><code>chains-exclude</code></td><td>CSV</td><td>Chain blocklist, showing all chains except these.</td></tr><tr><td><code>config</code></td><td>JSON string</td><td>SDK config patch for wallet/provider credentials.</td></tr><tr><td><code>sentry-dsn</code></td><td>string</td><td>Override the bundled telemetry DSN (web component only).</td></tr><tr><td><code>color-*</code></td><td>HSL string</td><td>Color theme tokens. See Theming.</td></tr><tr><td><code>border-radius</code></td><td>CSS length</td><td>Corner rounding. See Theming.</td></tr><tr><td><code>font-family</code></td><td>font stack</td><td>Widget font. See Theming.</td></tr></tbody></table>

Registered attributes are observed: mutating one re-renders the widget.

### Full props reference (React)

<table><thead><tr><th width="130">Prop</th><th width="188">Type</th><th width="136">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>widgetId</code></td><td><code>string</code></td><td>None</td><td>Widget ID. Pair with <code>widgetKey</code>.</td></tr><tr><td><code>widgetKey</code></td><td><code>string</code></td><td>None</td><td>Widget Key. Pair with <code>widgetId</code>.</td></tr><tr><td><code>apiKey</code></td><td><code>string</code></td><td>None</td><td>Alternative auth mode. Takes precedence over widget auth.</td></tr><tr><td><code>apiBaseUrl</code></td><td><code>string | null</code></td><td><code>https://api.swapkit.dev</code></td><td>Override the API base URL. Missing schemes are normalized.</td></tr><tr><td><code>inputAsset</code></td><td><code>string | null</code></td><td><code>BTC.BTC</code></td><td>Initial pay asset.</td></tr><tr><td><code>outputAsset</code></td><td><code>string | null</code></td><td><code>ETH.USDT-0x…</code></td><td>Initial receive asset.</td></tr><tr><td><code>theme</code></td><td><code>SwapKitThemeTokens</code></td><td>None</td><td>Theme tokens (colors, <code>radius</code>, <code>fontFamily</code>). See Theming.</td></tr><tr><td><code>colors</code></td><td><code>SwapKitThemeTokens</code></td><td>None</td><td>Deprecated alias for <code>theme</code>, kept for backwards compatibility.</td></tr><tr><td><code>wallets</code></td><td><code>WalletConfig</code></td><td><code>"all"</code></td><td>Wallet allow/deny configuration.</td></tr><tr><td><code>chains</code></td><td><code>ChainConfig</code></td><td><code>"all"</code></td><td>Chain allow/deny configuration.</td></tr><tr><td><code>config</code></td><td><code>{ apiKeys?; integrations? }</code></td><td>None</td><td>SDK credentials payload for wallet providers.</td></tr><tr><td><code>developMode</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Enable developer mode (experimental wallets, dev API URL).</td></tr><tr><td><code>devApiUrl</code></td><td><code>string | null</code></td><td>None</td><td>API URL used when <code>developMode</code> is <code>true</code>.</td></tr><tr><td><code>className</code></td><td><code>string</code></td><td>None</td><td>Extra class name on the widget root.</td></tr><tr><td><code>disableTelemetry</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Disable the widget's Sentry telemetry.</td></tr><tr><td><code>syncUrl</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Sync selected assets and amount to URL query params.</td></tr></tbody></table>

The React component exposes `disableTelemetry` rather than a DSN override; `sentry-dsn` exists only on the web component path.

***

### Troubleshooting

**API requests fail authentication.** Confirm that either `api-key` is present, or both `widget-id` and `widget-key` are present. For dashboard-created embeds, prefer the widget pair.

**Works locally but fails in production.** Confirm the production domain matches the domain registered under Widget Keys, and that you did not include `https://` when creating the domain key.

**A rotated key stopped the widget.** Update the deployed snippet with the new Widget Key. The old one stops working immediately after rotation.

**A wallet does not appear.** Check `wallets` / `wallets-include` / `wallets-exclude`, confirm the wallet supports at least one widget-supported chain, and note that hardware and desktop-only options are hidden on mobile and experimental wallets are hidden outside Developer Mode.

**Custom colors do not apply.** Use HSL channel values without `hsl()`: `155 86% 62%`, not `hsl(155 86% 62%)`.

**The widget renders unstyled (React).** Import `@swapkit/ui/swapkit.css` once at your app root.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.swapkit.dev/swapkit-widget/configuring-in-code.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
