Skip to Content

Frontend - Defining Themes

June 2, 2026 by
Frontend - Defining Themes
渥屋科技股份有限公司, 系統管理者
Frontend

Frontend

The Frontend integration is what renders the official WoowTech web interface that you use to operate your home. It comes on automatically as part of default_config:, so most installations never touch it. Should you have stripped default_config: out of your configuration.yaml, you can switch the interface back on with a single line:

frontend:

What you can configure

Option Type What it controls
themes map Your own named color themes. Detailed below.
extra_module_url list Extra JavaScript modules served to modern (latest) browsers.
extra_js_url_es5 list Extra JavaScript served to legacy (es5) browsers.
development_repo string Path to a local checkout of the frontend source, for development.
development_pr integer A frontend pull-request number to load instead of the bundled build (needs github_token).
github_token string A GitHub token used when fetching pull-request builds.

Building themes

A theme is a named set of CSS variables that recolors the interface. You declare each one beneath themes: and give it a key that becomes the theme's display name:

frontend:
  themes:
    sunrise:
      primary-color: "#e67e22"
      accent-color: "#16a085"
    midnight:
      primary-color: "#34495e"
      accent-color: "#9b59b6"

A small gotcha: put any hex color in quotes. A bare # at the start of a value reads as a YAML comment and the color silently disappears.

Which variables exist

Headline colors. primary-color and accent-color set the dominant tints used throughout the application.

Per-entity state colors. Entities can be tinted according to their domain, their device class, and their current state. WoowTech looks for a matching variable from most specific to least specific:

  1. state-{domain}-{device_class}-{state}-color
  2. state-{domain}-{state}-color
  3. state-{domain}-(active|inactive)-color
  4. state-(active|inactive)-color

Domains that participate include light, switch, cover, lock, climate, and many more. An example that targets a couple of specific cases:

frontend:
  themes:
    workshop:
      state-cover-garage-open-color: "#27ae60"
      state-media_player-inactive-color: "#607d8b"

Separate light and dark variants

A single theme can carry different values for light versus dark mode by nesting them under modes::

frontend:
  themes:
    tide:
      primary-color: "#ff7043"
      modes:
        light:
          secondary-text-color: "#556b2f"
        dark:
          secondary-text-color: "#708090"

Each user picks light or dark from their own profile page.

Keeping themes in their own files

If your theme list grows, pull it out of configuration.yaml:

  • One file: themes: !include all_themes.yaml
  • A whole folder, merged together: themes: !include_dir_merge_named theme_files

Choosing the active theme

Theme actions

Action Effect
frontend.reload_themes Re-reads your theme definitions without a restart.
frontend.set_theme Sets the server-wide default theme for light mode and, optionally, dark mode.

frontend.set_theme accepts:

Field Description
name The light-mode theme to apply; pass default to use the built-in WoowTech look.
name_dark The dark-mode theme; pass default for the standard look or none to clear an existing override.

A theme chosen this way survives restarts.

Per-user selection

Once themes are defined, each person can override the server default from the dropdown on their profile page. That choice follows them across whatever devices they sign in on.

Serving your own JavaScript

You can inject custom scripts for both modern and legacy browsers:

frontend:
  extra_module_url:
    - /local/dashboard_tweaks.js
  extra_js_url_es5:
    - /local/dashboard_tweaks.es5.js

Modern browsers pull the module form through import(), while older ones load the deferred ES5 build via a <script> tag. A given device only ever loads one of the two.

Picking a language by hand

WoowTech reads your browser's preferred language automatically, but if you want a different one you can override it from your profile page.

Start writing here...

Share this post