Appearance API
Every Cimplify Element iframe (`AuthElement`, `CheckoutElement`, `AccountElement`, the hosted Pay page) accepts an `appearance` object that controls theme, accent color, font, and corner radius. The same shape works across all integration tiers.
The type
Defined as ElementAppearance in @cimplify/sdk:
interface ElementAppearance {
theme?: "light" | "dark";
variables?: {
primaryColor?: string; // any CSS color
fontFamily?: string; // CSS font-family value
borderRadius?: string; // CSS length, e.g. "0.5rem"
};
}Defaults
From packages/link/src/lib/appearance.ts:
| Field | Default |
|---|---|
theme | "light" |
primaryColor | #059669 (Emerald 600) |
fontFamily | "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif |
borderRadius | 0.85rem |
Validation
The Element runs values through CSS.supports() before applying them; invalid values silently fall back to the default rather than rendering broken styles. Specifically:
primaryColormust be a valid CSS color (CSS.supports("color", value)); otherwise the default emerald is used.borderRadiusmust be a valid CSS length (CSS.supports("border-radius", value)); otherwise0.85rem.fontFamilyis rejected if it's longer than 160 chars, blank, or contains;,{, or}(basic CSS-injection guard).- Any value outside
"light"|"dark"is treated as"light".
Setting it
React
Memoize the appearance object. Iframe options are locked in at mount; passing a new reference triggers a console warning and is ignored to avoid remount churn.
import { useMemo } from "react";
import { CimplifyCheckout } from "@cimplify/sdk/react";
export function Checkout() {
const appearance = useMemo(
() => ({
theme: "dark" as const,
variables: {
primaryColor: "#7c3aed", // violet-600
fontFamily: "'Geist', sans-serif",
borderRadius: "0.5rem",
},
}),
[],
);
return (
<CimplifyCheckout
client={client}
cartId={cartId}
appearance={appearance}
onComplete={(r) => { /* … */ }}
/>
);
}Vanilla / Elements
const elements = createElements(client, businessId, {
appearance: {
theme: "dark",
variables: {
primaryColor: "#7c3aed",
borderRadius: "0.5rem",
},
},
});Embedded iframe (raw)
Pass it inside the init postMessage:
iframe.contentWindow!.postMessage({
type: "init",
businessId, publicKey,
appearance: {
theme: "light",
variables: { primaryColor: "#059669", borderRadius: "0.85rem" },
},
}, "https://link.cimplify.io");Hosted Pay session
Pass it on session create; Cimplify stores it and applies it when the page loads:
{
"cart_id": "crt_…",
"appearance": {
"theme": "light",
"variables": { "primaryColor": "#0a2540" }
}
}CSS variables exposed
Internally, the appearance is resolved into CSS custom properties on the iframe's root. The full set (for reference, not direct customization):
| Variable | Driven by |
|---|---|
--cimplify-primary-color | variables.primaryColor |
--cimplify-primary-color-alpha | 10% alpha mix of the primary |
--cimplify-border-radius | variables.borderRadius |
--cimplify-bg / --cimplify-text | theme + sane defaults |
--cimplify-surface / --cimplify-border | theme |
--cimplify-error / --cimplify-warning | fixed |
These are bridged into shadcn / Tailwind tokens (--primary, --background, --ring, etc.) so the iframe's entire UI re-themes from a single primary color.
Limits
- You can't inject custom CSS or class names into the iframe.
- You can't reorder or hide individual fields; for that level of control, use headless checkout.
- Font files have to be reachable from the customer's browser (i.e. system font stack or a webfont served from your own CDN with permissive CORS).
Next
- Controlled Elements: React surface that consumes
appearance - Headless checkout: Bring your own theming
Headless checkout
Drive the checkout API directly. No iframe, no Cimplify-rendered fields; every screen, every input, every microcopy is yours. Use this when the iframe's look or layout can't accommodate your brand, or when you're building a non-web surface (native app, kiosk, voice).
Universal Commerce Protocol (UCP)
A signed, capability-discoverable protocol AI agents use to browse, price, check out, and pay across any Cimplify business with verifiable consent.