# Theme the Editor UI

> Apply product colors to SuperDoc UI, then override one component when the semantic theme is not enough.



Use `createTheme()` to turn a small set of product tokens into SuperDoc CSS variables. Apply the returned class to
`<html>` so toolbars, menus, and surfaces mounted under `document.body` inherit the same theme.

## Try a theme [#try-a-theme]

Change a semantic color or the border radius, then open the dialog. Turn on **Toolbar override** to see when a
component-specific variable is useful.

> **Live example: theme the Editor UI**
>
> Change the semantic action, surface, text, border, or radius value and the real Editor updates. The dialog inherits the same theme because the generated class is applied to `<html>`. Turning on Toolbar override adds `--sd-ui-toolbar-bg` after the semantic values. The generated `ThemeConfig` code updates with each choice.


The DOCX content and formatting do not change. These tokens style the Editor UI around the document.

## Start with semantic tokens [#start-with-semantic-tokens]

Start from the [quickstart](/editor/quickstart) with `/sample.docx` in your application's `public` directory.

```ts
import { SuperDoc, createTheme, type ThemeConfig } from 'superdoc';
import 'superdoc/style.css';

const productTheme = {
  name: 'product',
  colors: {
    action: '#4f46e5',
    actionHover: '#4338ca',
    bg: '#f8fafc',
    text: '#1e293b',
    border: '#cbd5e1',
  },
  radius: '8px',
  // `colors.bg` also feeds `--sd-layout-page-bg`, which paints the document page. Pin the
  // page so a dark UI surface does not darken pages whose DOCX sets no background.
  vars: { '--sd-layout-page-bg': '#ffffff' },
} satisfies ThemeConfig;

const themeClass = createTheme(productTheme);
document.documentElement.classList.add(themeClass);

const superdoc = new SuperDoc({
  selector: '#editor',
  document: '/sample.docx',
});

window.addEventListener('beforeunload', () => superdoc.destroy());

```

`ThemeConfig` gives the object autocomplete and checks its shape. A stable `name` also makes the generated class
predictable—in this example, `sd-theme-product`.

Apply the class to `document.documentElement`, not only the Editor container. SuperDoc can mount dialogs, menus, and
other temporary surfaces under `document.body`, outside that container.

## Override one component [#override-one-component]

Set semantic values first so related controls stay consistent. Use `vars` only when one component needs to differ:

```ts
const productTheme = {
  name: 'product',
  colors: {
    action: '#4f46e5',
    bg: '#f8fafc',
    text: '#1e293b',
    border: '#cbd5e1',
  },
  vars: {
    '--sd-layout-page-bg': '#ffffff',
    '--sd-ui-toolbar-bg': '#eef2ff',
  },
} satisfies ThemeConfig;
```

TypeScript restricts `vars` keys to names that start with `--sd-`. These values take precedence over the semantic
values generated by the same theme.

`--sd-layout-page-bg` defaults to the theme's `bg`, which paints the document page as well as the Editor surface. Pin it
whenever `bg` is not near-white, or pages without an explicit DOCX background follow your UI color while their text does
not.

## Control style injection [#control-style-injection]

`createTheme()` injects a `<style>` element and returns its class name. For server rendering or a strict Content
Security Policy, use `buildTheme()` to receive `{ className, css }`, then pass the CSS through your application's
stylesheet or nonce-aware style pipeline. See [Secure integration](/editor/secure-integration) for the related CSP
requirements.

Emit that CSS after `superdoc/style.css`. The generated `.sd-theme-*` rule and the package defaults under `:root` have
the same specificity, so whichever loads last wins — a theme emitted first is silently replaced by the defaults.
`createTheme()` is unaffected, because it appends its `<style>` element to `document.head`.

## Verify the theme [#verify-the-theme]

Change the action color and open the dialog. The dialog action and active Editor controls should use the new color. The
toolbar background should change only when **Toolbar override** is on.
