# White-label the dashboard

Replace the Omnia name, logo, colours and fonts in the dashboard with your own brand.

## Prerequisites

- `enterprise.enabled=true` in your Helm values.
- Either no licence (dev mode, which grants every entitlement) or a licence with the
  `whiteLabel` entitlement. Without the entitlement the dashboard ignores the brand
  and shows the Omnia defaults. See [Install a licence](/how-to/operations/install-license/).
- Your logo and favicon as SVG files, hosted at an HTTPS URL or ready to mount in
  [the logo section](#serve-logos-from-the-dashboard-mount-via-helm).

## Set the brand

1. Add `dashboard.branding` to a values file. `productName` is required: the chart
   emits no branding without it.

   ```yaml
   enterprise:
     enabled: true

   dashboard:
     branding:
       productName: "Acme Cloud"
       logoDarkUrl: "https://assets.acme.example/acme-dark.svg"
       faviconUrl: "https://assets.acme.example/acme-favicon.svg"
       colors:
         primary: "#EA580C"
         primaryAction: "#F59E0B"
         accent: "#DC2626"
         sidebar: "#7C2D12"
         textHeading: "#FFF7ED"
       fonts:
         family: "Poppins"
         mono: "JetBrains Mono"
         url: "https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap"
       links:
         sales: "sales@acme.example"
         upgradeUrl: "https://acme.example/enterprise"
   ```

   The values above are illustrative. [Dashboard branding reference](/reference/platform/dashboard-branding/)
   lists every key `colors` accepts, including the Atlas aliases such as `textHeading`.

2. Upgrade the release. management-api, which serves the brand to the browser, restarts when the branding values change. Reload an open dashboard tab to see the new brand.

   ```bash
   helm upgrade omnia oci://ghcr.io/altairalabs/charts/omnia --devel \
     --namespace omnia-system --reuse-values -f brand.yaml
   ```

## Set dark-mode surfaces

Values in `colors` apply in both themes. A surface that must differ by theme goes in
`colorsDark`, which wins in the dark theme. The default theme is dark.

```yaml
dashboard:
  branding:
    colors:
      primary: "#EA580C"
      background: "#FFF7ED"
      card: "#FFFFFF"
      foreground: "#431407"
    colorsDark:
      background: "#1A120B"
      card: "#251A11"
      foreground: "#FFF7ED"
      mutedForeground: "#FDBA74"
      border: "rgba(253, 186, 116, 0.14)"
```

Accent colours (`primary`, `category1` to `category8`, `chart1` to `chart5`) usually
read well in both themes, so set them once in `colors`.

## Serve logos from the dashboard (mount via Helm)

Skip this section if your logos are hosted at an HTTPS URL.

`logoDarkUrl` and `faviconUrl` accept a path served by the dashboard. The dashboard
serves `/usr/share/nginx/html/` at the site root, so a file at
`/usr/share/nginx/html/brand/logo-dark.svg` is served at `/brand/logo-dark.svg`.

1. Put the assets in a ConfigMap in the release namespace.

   ```bash
   kubectl create configmap dashboard-logos -n omnia-system \
     --from-file=logo-dark.svg=./acme-dark.svg \
     --from-file=favicon.svg=./acme-favicon.svg
   ```

2. Mount each file under `/usr/share/nginx/html/brand/` and point the branding values at those
   paths.

   ```yaml
   dashboard:
     branding:
       productName: "Acme Cloud"
       logoDarkUrl: "/brand/logo-dark.svg"
       faviconUrl: "/brand/favicon.svg"

     extraVolumes:
       - name: brand-logos
         configMap:
           name: dashboard-logos

     extraVolumeMounts:
       - name: brand-logos
         mountPath: /usr/share/nginx/html/brand/logo-dark.svg
         subPath: logo-dark.svg
         readOnly: true
       - name: brand-logos
         mountPath: /usr/share/nginx/html/brand/favicon.svg
         subPath: favicon.svg
         readOnly: true
   ```

   `podOverrides.extraVolumes` and `podOverrides.extraVolumeMounts` append to the same
   lists.

:::caution
Mount per file with `subPath` into a subdirectory such as `/brand/`. A volume mounted
over `/usr/share/nginx/html` hides the dashboard itself. A `subPath` ConfigMap mount does not
reload: after you change a logo, run `kubectl rollout restart` on the dashboard
Deployment or rename the ConfigMap.
:::

The licence gate applies to mounted files too. Mounting a file over the built-in
`/logo-omnia.svg` to bypass the gate is a licence violation. Keep custom assets on a
distinct path such as `/brand/`.

## Load a custom font

`fonts.url` must be a CSS stylesheet URL, such as a Google Fonts `href`, not a font
file. The default Content-Security-Policy allows `fonts.googleapis.com` and
`fonts.gstatic.com`. For another host, set `OMNIA_CSP_POLICY` on the dashboard. It
replaces the whole default policy, so copy every directive you still need. If the
font fails to load, the interface falls back to the system sans-serif stack.

## Set the link-preview card

A link to the dashboard pasted into Slack, Teams or LinkedIn unfurls into a card,
`/og-image.png`. The dashboard is built once for every install, so the card it ships
carries the Omnia brand, and so does the page title a scraper reads: it runs no
JavaScript, so it never sees your brand. Point `/og-image.png` at your own card, a
1200x630 PNG at an HTTPS URL:

```yaml
dashboard:
  branding:
    ogImageUrl: "https://assets.acme.example/acme-card.png"
```

The dashboard answers `/og-image.png` with a redirect to it. Set `dashboard.baseUrl`
too, so the card's URL in the page names your public address rather than the one each
request arrived on.

## Verify

1. Forward the dashboard and read the resolved brand.

   ```bash
   kubectl port-forward -n omnia-system svc/omnia-dashboard 3000:3000
   curl -s http://localhost:3000/api/v1/config
   ```

   The `brand.productName` field in the JSON is your product name. It is `Omnia`
   when the licence lacks `whiteLabel` or the chart emitted no branding.

2. Open `http://localhost:3000`. The sidebar shows your product name and logo, and the
   browser tab reads `<productName> Dashboard` once the page has loaded its
   configuration.

To preview a brand without a cluster, run the dashboard in dev or demo mode and use
**Brand preset (dev)** in the **More actions** menu, or open `/dev/theme`. See
[Preview controls](/reference/platform/dashboard-branding/#preview-controls).

## Troubleshooting

### The dashboard still shows Omnia

Check three conditions: `enterprise.enabled` is `true`, `dashboard.branding.productName`
is set, and the licence carries `whiteLabel`. Run
`kubectl describe configmap omnia-dashboard -n omnia-system` and confirm
`NEXT_PUBLIC_BRAND_PRODUCT_NAME` is present.

### One colour does not change

`colors` ignores keys it does not recognise, so a typo costs that one colour. Use the
camelCase keys from the [colour keys table](/reference/platform/dashboard-branding/#colour-keys),
not CSS variable names. No key sets `--destructive`.

### The logo does not load

An `http:` image URL is blocked by the default Content-Security-Policy. Use an HTTPS URL
or a mounted path.

## Related pages

- [Dashboard branding reference](/reference/platform/dashboard-branding/): Helm values,
  environment variables, colour keys, Atlas aliases and precedence.
- [Install a licence](/how-to/operations/install-license/)
- [Licensing](/explanation/platform/licensing/)
- [Helm values reference](/reference/platform/helm-values/#branding-white-label)