Ecosystem ↗

Runtime theme configuration

Configure server/browser theme helpers and distinguish them from the static docs appearance control.

↗ View Markdown

Runtime theme options#

zerux.config.ts
import type { ZeruxConfig } from 'zeruxjs';
const theme = {
  default: 'system', cookieName: 'theme',
  disablePreferenceHeader: false,
  scriptPosition: 'head', scriptType: 'module', scriptLoadType: 'async',
} satisfies NonNullable<ZeruxConfig['theme']>;
export default { theme } satisfies ZeruxConfig;

The same object works in JavaScript with a JSDoc config annotation. This is configuration for the framework theme helpers, not a replacement for Zuixs CSS generation or application component classes. The docs static app currently uses its own shared localStorage-based appearance control; that behavior does not demonstrate runtime cookie-based theme middleware.

Defaults and compatibility#

Valid modes are light, dark and system; an absent or invalid default normalizes to system. The cookie name defaults to theme. Both disablePrefrenceHeader (legacy spelling) and disablePreferenceHeader are accepted; the legacy field takes precedence when both are set. Prefer the correctly spelled field in new configuration and avoid setting both.

Script position is head, body-top or body, defaulting to head. Type is module or nomodule, defaulting to module. Load type is async or defer, defaulting to async. These options describe injection behavior; they do not make arbitrary theme scripts compatible with a restrictive CSP. Use the application's actual nonce/hash policy where scripts are emitted.

Ownership and browser behavior#

A server resolves theme preference from the relevant request/cookie context. A browser may also have an operating-system preference. Keep preference values validated and do not let an arbitrary cookie value become raw HTML or CSS. Theme cookies are not authentication cookies, but cookie serialization still needs safe names and values.

Apply theme-aware surface, text, border and focus tokens together. Testing only the page background misses hard-coded white inputs or cards. Include the open menu, search dialog, hovered and keyboard-focused states in both schemes. Respect reduced-motion preferences independently of theme.

Verify the integration#

Check the server-rendered preference on the first response, the system fallback with no stored value, explicit light on a dark system, explicit dark on a light system, and a malformed cookie. If a flash appears before paint, inspect script position and stylesheet timing. Static exports have no per-request Node theme resolution, so restore public appearance preferences in a small early browser script or rely on CSS media queries.

Exact option shapes#

The fields below come from the current source declarations. Optional is not a default value. A callback is application code, not a string naming a role.

ThemeConfig#

Option Accepted TypeScript value Required Meaning
default ThemeMode No Passed using this declared shape; omission is allowed only when marked optional.
cookieName string No Passed using this declared shape; omission is allowed only when marked optional.
disablePrefrenceHeader boolean No Passed using this declared shape; omission is allowed only when marked optional.
disablePreferenceHeader boolean No Passed using this declared shape; omission is allowed only when marked optional.
scriptPosition "head" | "body-top" | "body" No Passed using this declared shape; omission is allowed only when marked optional.
scriptType "module" | "nomodule" No Passed using this declared shape; omission is allowed only when marked optional.
scriptLoadType "async" | "defer" No Passed using this declared shape; omission is allowed only when marked optional.

ResolvedThemeConfig#

Option Accepted TypeScript value Required Meaning
default ThemeMode Yes Passed using this declared shape; omission is allowed only when marked optional.
cookieName string Yes Passed using this declared shape; omission is allowed only when marked optional.
disablePrefrenceHeader boolean Yes Passed using this declared shape; omission is allowed only when marked optional.
scriptPosition "head" | "body-top" | "body" Yes Passed using this declared shape; omission is allowed only when marked optional.
scriptType "module" | "nomodule" Yes Passed using this declared shape; omission is allowed only when marked optional.
scriptLoadType "async" | "defer" Yes Passed using this declared shape; omission is allowed only when marked optional.
Implementation sources

Implementation files for the APIs described on this page.

ZeruxJS · Open source · MIT OR Apache-2.0

Make yourself at home.

Every shortcut has a visible control too. Reading and navigation work without JavaScript.

Ctrl / ⌘ K
Search all documentation
/
Search, outside editable fields
?
This help, outside editable fields
↑ / ↓
Move through search results
Esc
Close a dialog or version menu
Progress, privacy, offline reading and controls →

Reset this learning record?

This removes course answers, exercise confirmations, bookmarks and recent pages for this docs version in this browser. Export a copy first if you want to keep it.

Search documentation

Type at least two characters.