Every widget reads its visual tokens through a three-layer cascade. Each later layer overrides the previous one, so you can configure broad defaults at the brand-kit level and fine-tune individual widgets in code.
LAYER 1
Tenant brand kit
Configured once in Storefront → Customize. Logo, primary color, text color, font. Aforo fetches this when the widget mounts.
LAYER 2
CSS variables
Override at the page level via custom properties on :root or a containing element. Cascades naturally.
LAYER 3
Per-widget overrides
The themeOverrides prop / data-theme-overrides attribute. Highest specificity. Use for one-off tuning.
INFO
If the tenant brand kit isn't configured (new tenants), the SDK falls back to a neutral default palette. Your widgets won't look broken; they'll just look generic until you fill in the brand kit.
Loading skeletons honor prefers-reduced-motion: reduce — the shimmer animation pauses for users who've opted out of motion. No prop needed; it's automatic.
The widgets use 100% logical CSS properties (margin-inline-start, padding-inline-end, inset-inline-start) — no margin-left or padding-right. Setting dir="rtl" on the page or a containing element flips the layout automatically.
ar.html
<!-- Set dir at the document level or on a containing element -->
<html lang="ar" dir="rtl">
<body>
<div
data-aforo-widget="pricing-card"
data-tenant-slug="acme"
data-embed-key="embk_live_…"
data-locale="ar-AE"
></div>
</body>
</html>
Currency and date formatting use the standard Intl API — pass locale (default: navigator.language) to override the formatting locale for amounts and dates.
Every widget class is namespaced (aforo-w-pc-* for pricing card, aforo-w-sb-* for subscribe button, etc.) so the widgets won't collide with your CSS. We never use !important — your own styles can override anything via normal specificity.
import { useTheme } from '@mui/material';
export function AforoThemeBridge({ children }: { children: React.ReactNode }) {
const theme = useTheme();
return (
<div
style={{
// Map MUI palette → Aforo CSS variables
['--aforo-color-primary' as any]: theme.palette.primary.main,
['--aforo-color-on-primary' as any]: theme.palette.primary.contrastText,
['--aforo-font-family' as any]: theme.typography.fontFamily,
}}
>
{children}
</div>
);
}
Plain CSS
Drop the CSS variables block in your stylesheet at :root and you're done. The widgets pick them up automatically — no JavaScript needed.
INFO
Live preview your theme in Embed Studio → Widgets → Configure. The mock preview pane shows the actual widget with your brand kit applied, before you deploy any embed code.