Skip to main content

Your brand, no build step.

A daisyUI 5 theme is nothing but a block of CSS custom properties scoped to a data-theme selector — so ApiGlow can accept yours at runtime. Two channels exist, by design, and both take the daisyUI theme generator’s output as-is.

Channel 1: the config

Declare the theme in theme.custom; the app generates and injects its CSS at boot.

{
  "theme": {
    "default": "acme",
    "available": ["acme", "light", "dark"],
    "custom": [
      {
        "name": "acme",
        "extends": "dark",
        "tokens": {
          "--color-primary": "#6d28d9",
          "--color-primary-content": "#f5f3ff",
          "--radius-box": "0.5rem"
        }
      }
    ]
  }
}
  • name — required, [a-z][a-z0-9-]*. Naming it after a built-in theme (light, dark, …) restyles that theme in place — the cheapest “keep light and dark, brand the primary” path.
  • extends — optional, any built-in daisyUI theme to inherit from. The primary use case is “dark, but in our colors”: a handful of tokens. Without it, unset tokens fall back to the build’s default theme, so declare the full set — the generator emits every token anyway. Extending another custom theme is not supported.
  • colorScheme — optional "light" or "dark", drives browser-provided UI (scrollbars, form controls). Inherited from extends when absent.
  • tokens — daisyUI 5 theme variables under their verbatim names: the twenty --color-*, the radii and sizes, --border, --depth, --noise. This is why generator output pastes straight in.

List the theme in theme.available too, or it is injected but not selectable.

Channel 2: your own CSS

Zero config beyond the listing: a plain block in the host page’s stylesheet, and the name in theme.available.

[data-theme="acme"] {
  color-scheme: dark;
  --color-primary: #6d28d9;
  --color-primary-content: #f5f3ff;
  /* …the rest of the daisyUI theme variables… */
}

Undefined tokens fall back to the default theme’s values. When the goal is restyling a built-in theme name in place, prefer the config channel: it mirrors daisyUI’s own selectors, so it keeps working regardless of how daisyUI layers its styles.

Validation is lenient, on purpose

A theme is a styling concern, so nothing about it is allowed to break the page: an unknown token or an invalid value is skipped with a console warning, a custom name missing from available is flagged (likely a config mistake) but still injected, and a duplicate name warns and keeps the first. The worst a bad theme can do is look wrong.

In multi-spec

theme.custom is root-only — themes are global chrome, injected once at boot. A specs[] entry may still override theme.default and theme.available: a spec narrows what is selectable, it never defines a theme. Details in the multi-spec guide.

The rest of the branding story — product name, logo, footer links, and the one thing that always stays — lives on the Theming & branding feature page.