Skip to main content

Customize AGG UI

AGG UI is designed to be embedded in partner apps without forking components. The supported customization surface is:
  • CSS variables on the AGG root for brand, typography, radius, shadow, and z-index tokens
  • AggProvider config for theme mode, labels, formatting, feature flags, search wiring, and wallet actions
  • component className / classNames props for layout composition
Import @agg-build/ui/styles.css once, then load your app CSS after it. AGG defaults are low specificity, so :root overrides can work, and .agg-root overrides win because they are closer to the AGG UI tree.

Minimal integration

app/providers.tsx
import "@agg-build/ui/styles.css";
import "./agg-theme.css";

import { AggProvider, QueryClient, QueryClientProvider } from "@agg-build/hooks";
import { createAggClient } from "@agg-build/sdk";
import type { ReactNode } from "react";

const client = createAggClient({
  baseUrl: "https://api.agg.market",
  appId: "your-app-id",
  wsUrl: "wss://ws.agg.market/ws",
});

const queryClient = new QueryClient();

export function Providers({ children }: { children: ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      <AggProvider
        client={client}
        config={{
          general: {
            locale: "en-US",
            theme: "light",
            rootClassName: "acme-agg-theme",
          },
          features: {
            enableAnimations: true,
            enableLiveUpdates: true,
            enableGradients: false,
            showFeesBreakdown: true,
          },
        }}
      >
        {children}
      </AggProvider>
    </QueryClientProvider>
  );
}
app/page.tsx
import { HomePage } from "@agg-build/ui/pages";

export default function Page() {
  return <HomePage withHeader />;
}
AggProvider renders an .agg-root wrapper around its children. If you pass general.rootClassName, that class is added to the same root so you can scope partner-specific branding without affecting other AGG embeds on the page.

Import order

Load AGG styles first and partner overrides second:
import "@agg-build/ui/styles.css";
import "./agg-theme.css";
Then put variables in your CSS:
agg-theme.css
.agg-root.acme-agg-theme {
  --agg-color-primary: #2563eb;
  --agg-color-primary-hover: #1d4ed8;
  --agg-color-secondary: #ffffff;
  --agg-color-secondary-hover: #f1f5f9;
  --agg-color-border: #cbd5e1;
  --agg-color-foreground: #0f172a;
  --agg-color-muted-foreground: #475569;
  --agg-color-on-primary: #ffffff;
  --agg-radius-md: 0.625rem;
  --agg-radius-full: 0.75rem;
  --agg-shadow-card: 0 8px 20px rgb(15 23 42 / 0.08);
}

Custom fonts

Set the AGG font token on .agg-root. This affects AGG typography utilities, primitives, pages, modals, and portaled surfaces.

Plain CSS

.agg-root {
  --agg-font-family-sans: "Your Font", ui-sans-serif, system-ui, sans-serif;
}
You can also set the token on :root; a value on .agg-root wins if both exist.

Next.js next/font

Expose the generated font variable on an ancestor, then map it into the AGG token.
app/layout.tsx
import { Inter } from "next/font/google";
import { Providers } from "./providers";
import "./globals.css";

const inter = Inter({
  subsets: ["latin"],
  variable: "--font-inter",
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={inter.variable}>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
globals.css
.agg-root {
  --agg-font-family-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}

Light and dark themes

general.theme controls the class and data attributes applied to .agg-root. If you ship custom dark tokens, match AGG’s dark selector shape so your values win in dark mode:
:where(
  .dark .agg-root.acme-agg-theme:not(.light),
  .agg-dark .agg-root.acme-agg-theme:not(.light),
  .agg-root.acme-agg-theme.dark,
  .agg-root.acme-agg-theme[data-agg-theme="dark"]
) {
  --agg-color-primary: #8fb4ff;
  --agg-color-primary-hover: #b4ccff;
  --agg-color-secondary: #0b1220;
  --agg-color-secondary-hover: #172036;
  --agg-color-border: #334155;
  --agg-color-foreground: #e2e8f0;
  --agg-color-muted-foreground: #94a3b8;
  --agg-color-on-primary: #121214;
  --agg-shadow-card: 0 10px 28px rgb(2 6 23 / 0.45);
}

Gradients

Keep semantic colors and gradient definitions separate. features.enableGradients controls whether branded surfaces resolve to flat primary colors or gradient tokens.
<AggProvider
  client={client}
  config={{
    features: {
      enableGradients: true,
    },
  }}
>
  <HomePage />
</AggProvider>
.agg-root.acme-agg-theme {
  --agg-gradient-brand: linear-gradient(90deg, #2563eb, #4f46e5);
  --agg-gradient-brand-hover: linear-gradient(90deg, #1d4ed8, #4338ca);
}

:where(
  .dark .agg-root.acme-agg-theme:not(.light),
  .agg-dark .agg-root.acme-agg-theme:not(.light),
  .agg-root.acme-agg-theme.dark,
  .agg-root.acme-agg-theme[data-agg-theme="dark"]
) {
  --agg-gradient-brand: linear-gradient(90deg, #8fb4ff, #c084fc);
  --agg-gradient-brand-hover: linear-gradient(90deg, #b4ccff, #d8b4fe);
}

Public theme tokens

Set these on .agg-root or .agg-root.<your-rootClassName>.
TokenUsage
--agg-color-primaryPrimary CTA color and emphasis states
--agg-color-primary-hoverPrimary action hover color
--agg-color-secondaryCard, popover, modal, and control surfaces
--agg-color-secondary-hoverNeutral hover and selected surfaces
--agg-color-borderBorders and separators
--agg-color-foregroundPrimary text and icon foreground
--agg-color-muted-foregroundSecondary text, metadata, and helper labels
--agg-color-on-primaryText and icons on branded filled surfaces
--agg-color-successPositive status and bid-side color
--agg-color-warningWarning status
--agg-color-errorError status and ask-side color
--agg-color-overlayModal and drawer overlay color
--agg-gradient-brandBranded gradient fill
--agg-gradient-brand-hoverBranded gradient hover fill
--agg-font-family-sansBase AGG UI font family
--agg-font-size-2xs through --agg-font-size-4xlTypography size scale
--agg-line-height-3, --agg-line-height-14, --agg-line-height-4 through --agg-line-height-10, --agg-line-height-baseTypography line-height scale
--agg-font-weight-normal, --agg-font-weight-medium, --agg-font-weight-semibold, --agg-font-weight-boldTypography weight scale
--agg-radius-sm, --agg-radius-md, --agg-radius-lg, --agg-radius-xl, --agg-radius-2xl, --agg-radius-fullRadius scale
--agg-shadow-card, --agg-shadow-popover, --agg-shadow-modalElevation tokens
--agg-z-index-dropdown, --agg-z-index-overlay, --agg-z-index-modal, --agg-z-index-toast, --agg-z-index-tooltipDropdown, overlay, modal, toast, and tooltip layering
Avoid overriding bridge tokens such as --color-agg-*, --text-agg-*, and --font-agg-sans directly. They are generated from the public --agg-* tokens.

Copy and labels

Use general.labels when you need to change user-facing text. Label overrides are deep-merged with AGG defaults, so you only provide the keys you want to replace.
<AggProvider
  client={client}
  config={{
    general: {
      labels: {
        common: {
          retry: "Try again",
        },
        auth: {
          signIn: "Sign in to Acme",
          deposit: "Add funds",
        },
        eventList: {
          emptyTitle: "No markets match your filters",
        },
      },
    },
  }}
>
  <HomePage />
</AggProvider>
Use labels for product copy. Use CSS variables for visual styling. Use component props for data, callbacks, and layout.

Formatting

Override formatting functions when your app needs a different locale, currency presentation, or date style.
const usdCompact = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  notation: "compact",
  maximumFractionDigits: 1,
});

<AggProvider
  client={client}
  config={{
    general: {
      locale: "en-US",
    },
    formatting: {
      formatCompactCurrency: (value) => usdCompact.format(value),
    },
  }}
>
  <HomePage />
</AggProvider>;

Layout and slots

Use className / classNames for layout composition, not deep CSS selectors.
import { HomePage } from "@agg-build/ui/pages";

export function MarketHome() {
  return (
    <HomePage
      withHeader={false}
      classNames={{
        root: "min-h-screen",
        header: "border-b border-slate-200 bg-white/90 backdrop-blur",
        tabs: "mx-auto w-full max-w-6xl px-6",
        sections: "mx-auto w-full max-w-6xl px-6 py-8 gap-8",
      }}
    />
  );
}
Prefer token overrides for colors, fonts, radius, shadows, and other repeated visual decisions. Use slot class names for spacing, containment, sticky behavior, or one-off layout requirements.

Troubleshooting

Make sure @agg-build/ui/styles.css is imported before your app CSS, and set --agg-font-family-sans on .agg-root. With next/font, put the generated font variable on an ancestor of AggProvider.
Scope variables to .agg-root and pass a stable general.rootClassName if you have multiple embeds. AGG portaled surfaces also carry .agg-root, so the same scoped token block applies.
Add a dark-mode override block using AGG’s selector shape. Light tokens and dark tokens are separate.
AGG internals use AGG token utilities. Override --agg-* variables for global theming, and use documented className / classNames props for layout slots.

Storybook Customization

Interactive token guide and live component catalog.

Theme Studio

Import a URL, inspect extracted brand tokens, and export CSS.

Setup Guide

Provider setup for SDK, hooks, UI components, and auth.

Components Overview

Curated references for pages, trading surfaces, events, and auth UI.