Custom themes
Build, share, and apply your own ServerBee theme variables.
ServerBee includes preset themes, and administrators can also create full custom themes. A custom theme stores OKLCH CSS variables for light and dark mode in the database, so the dashboard and public status pages can resolve the same theme everywhere.
Concepts
- Preset themes are immutable and ship with the web app.
- Custom themes are stored in the server database.
- The active admin theme controls the dashboard theme for all users.
- Each public status page can use its own theme or follow the active admin theme.
Create a theme
- Open Settings → Appearance.
- In My themes, click New theme.
- Enter a name and choose a preset to fork from.
- Edit the light and dark variables in the theme editor.
- Save the theme.
Apply a theme
- Dashboard: click any preset or custom theme card on Settings → Appearance.
- Status page: edit a status page and choose a theme from the Theme selector.
- To inherit the dashboard theme on a status page, choose Follow admin default.
Import and export
Use Export in the editor to download a theme JSON file. Use Import on the appearance page to upload one.
The import format is:
{
"version": 1,
"name": "Theme name",
"description": "Optional description",
"based_on": "default",
"vars_light": {},
"vars_dark": {}
}Only version: 1 is accepted.
Validation
- Every required variable must exist in both light and dark maps.
- Values must use
oklch(L C H)oroklch(L C H / alpha)syntax. Lmust be between0and1.Hmust be between0and360.- Alpha must be between
0and1, or between0%and100%. - Chroma has no hard cap. Browsers may gamut-clip values that cannot be displayed.
Branding and White Label
The same Settings → Appearance page also controls basic product branding. Branding settings are stored in the server database and are read by both the dashboard shell and public pages.
| Field | Description |
|---|---|
site_title | Browser/app title shown by the UI |
footer_text | Footer text shown where the UI renders a product footer |
logo_path | Public path for the uploaded logo, usually /api/brand/logo |
favicon_path | Public path for the uploaded favicon, usually /api/brand/favicon |
Public endpoints:
| Method | Path | Description |
|---|---|---|
| GET | /api/settings/brand | Read brand configuration without authentication |
| GET | /api/brand/logo | Serve uploaded logo |
| GET | /api/brand/favicon | Serve uploaded favicon |
Admin endpoints:
| Method | Path | Description |
|---|---|---|
| PUT | /api/settings/brand | Update site_title, footer_text, logo_path, and favicon_path as JSON |
| POST | /api/settings/brand/logo | Upload a logo via multipart field file |
| POST | /api/settings/brand/favicon | Upload a favicon via multipart field file |
Logo and favicon uploads accept PNG or ICO files only and are limited to 512 KB. Uploading a new asset replaces the previous asset of the same type.
PUT /api/settings/brand expects JSON. Image files are uploaded through the dedicated logo/favicon endpoints, not through the JSON update endpoint.
Disable custom themes
Set:
[feature]
custom_themes = falseOr set SERVERBEE_FEATURE__CUSTOM_THEMES=false.
When disabled, custom theme mutation endpoints reject writes, and any active custom:* reference is resolved as the default preset at read time. Stored themes are preserved.