Blog / EXECUTION

Theme the RAVN swap widget: playground, config, and code

One config object controls color, shape, and font. Try it live in the playground first, then copy the exact snippet into your app.

Quick answer

The embeddable swap widget takes a single config object on createRavnWidgetBridge: ten fields for color, corner radius, and font family, no CSS required. A public widget playground renders the real widget against your choices live, with four starting presets and a copy button that hands you the exact code to paste into your project.

Try it first: the playground

Before writing any config, open app.ravn.exchange/widget/playground. The left panel has color pickers for every themeable field, a corner-radius slider, and a font-family dropdown. The right panel is not a mockup: it is the real /widget/v1 route running in an iframe, driven by the same @ravnexchange/widget-connector bridge you would use in production. Change a color and the preview remounts a moment later with the new config applied, the same handshake a real integration runs once at load.

Four presets are built in to start from: Default, Violet, Watermelon (a light palette), and Mono. Pick one, nudge a few fields, then hit Copy. The playground writes out a complete createRavnWidgetBridge call with your exact config baked in, ready to drop into your codebase.

The full config reference

FieldTypeControls
primaryColorCSS colorThe swap button and other CTA/highlight surfaces
secondaryColorCSS colorTab underline and a few glow accents
backgroundCSS colorThe widget's own backdrop, behind the card
cardBackgroundCSS colorThe card shell. Every recessed surface inside it (inputs, the token chip, dropdown rows) gets a shade darker automatically, so they stay visibly recessed
textPrimaryCSS colorPrimary text
textSecondaryCSS colorMuted/secondary text
successCSS colorCompleted swaps and positive states
errorCSS colorError and alert states
borderRadiusnumber (px)Corner radius on every control and the card shell together
fontFamilyCSS font-family stringEvery piece of text in the widget

All ten are optional. Leave a field out and the widget's default token is used, so a partial theme (say, just primaryColor and borderRadius) is a normal, supported case, not an edge case.

The code

Theming rides on the same bridge that connects the widget to your page's wallet, one extra key on the same call:

npm install @ravnexchange/widget-connector
import { createRavnWidgetBridge } from "@ravnexchange/widget-connector";

const bridge = createRavnWidgetBridge({
  iframe: iframeRef.current,
  widgetOrigin: "https://app.ravn.exchange",
  getWallet: () => myConnectedWallet, // or null while none is connected
  config: {
    primaryColor: "#7C3AED",
    secondaryColor: "#A78BFA",
    borderRadius: 16,
    fontFamily: "Georgia, serif",
  },
});

The widget iframe reads config once, at load, over the same bridge handshake used for wallet signing. There is no separate theming endpoint and no re-render step to wire up on your end. Full field-by-field reference: docs.ravn.exchange/sdks/widget-theming.

Three presets, three different widgets

  • VioletA purple accent, 16px corners, and a serif font. Everything else stays default: proof that changing two colors and a radius is enough to stop looking like a stock embed.
  • WatermelonThe one built-in light theme: pink and rose accents over a white card on a pale pink backdrop, dark text set explicitly. Since there is no light/dark toggle, this is what a light theme looks like as a plain set of color fields.
  • MonoNear-black primary and secondary colors with square corners. Worth trying specifically because a very dark primaryColor is the case that used to make the swap button's own label unreadable, the widget now picks whichever label color actually contrasts against what you set.

What theming does not cover yet

Three gaps worth knowing about before you rely on them: there is no dedicated warning color, the widget's UI has no separate warning state to map it to. There is no single light/dark mode switch, a light look is a palette you set yourself, not a toggle. And there are no per-surface shadow or border on/off controls. None of these are silently unsupported: the fields above are the full surface, and the docs list the same three gaps rather than leaving you to discover them by trial and error.

Fonts: set, not fetched

fontFamily sets the CSS property inside the widget and nothing else. If you choose a font your visitors will not already have installed, loading it is still on you, a <link> tag or your existing font pipeline, exactly like any other web font on your page. The playground loads Google Fonts itself purely so its own preview renders correctly; that loading step is not something the production widget does for you.

Start theming

Try a palette in the playground, copy the config, paste it into your own createRavnWidgetBridge call.

FAQ

Do I need to write CSS to theme the widget?

No. Theming is one config object passed to createRavnWidgetBridge: ten fields covering colors, corner radius, and font family. No stylesheet, no shadow DOM overrides, no CSS to fight.

Is there a way to try themes before writing code?

Yes. The widget playground at app.ravn.exchange/widget/playground renders the real widget in an iframe against your color and font choices, with four starting presets, and generates the exact config object and code snippet to copy into your project.

Can I make the widget light-themed?

Yes, by setting background, cardBackground, textPrimary, and textSecondary yourself, the same way the playground's Watermelon preset does. There is no single light/dark toggle: you are picking a palette, not flipping a switch.

Does theming load a font for me?

No. fontFamily only sets the CSS property inside the widget. If you pick a font your visitors do not already have, you still need to load it on your own page or in your own font pipeline, same as any other web font.

Does theming require an API key or cost anything?

No. Theming is a client-side config object, not an API call. It works on the same anonymous, zero-fee tier as the rest of the widget and SDKs.

What can't I theme yet?

There is no warning color field (the UI has no separate warning state), no per-surface shadow or border toggles, and no light/dark mode switch, only the color fields above. The full field reference is in the docs.

Continue reading