Skip to content

Theme ​

Ooko follows the browser or operating-system color preference by default and exposes useOokoTheme for persistent light and dark overrides.

Automatic theme ​

When data-ooko-theme is absent, Ooko uses prefers-color-scheme:

html
<html>
  <!-- The Ooko theme follows the system preference. -->
</html>

This behavior is implemented in CSS, so the automatic light or dark palette does not depend on Vue or JavaScript. Ooko also sets color-scheme so compatible native controls follow the same theme.

Explicit theme containers remain supported:

html
<section data-ooko-theme="dark">
  <!-- This section is always dark. -->
</section>

Use data-ooko-theme="light" for an explicit light scope. Removing the attribute returns that scope to its inherited or system theme.

Vue composable ​

Import the composable from the dedicated package entry:

vue
<script setup lang="ts">
import { useOokoTheme } from "ooko-ui/theme";

const { mode, resolvedTheme, setMode } = useOokoTheme();
</script>

<template>
  <button type="button" @click="setMode('light')">Light</button>
  <button type="button" @click="setMode('dark')">Dark</button>
  <button type="button" @click="setMode('system')">System</button>

  <p>Preference: {{ mode }}</p>
  <p>Applied theme: {{ resolvedTheme ?? "Waiting for the browser" }}</p>
</template>

Call useOokoTheme from a long-lived component such as the application root. Calls share the same document-level state, while listener ownership follows mounted consumers.

API reference ​

Manages the document-level light, dark, or system theme preference.

ts
function useOokoTheme(): UseOokoThemeReturn

Parameters ​

ParameterTypeRequiredDefaultDescription
nonenonenonenonenone

Returns ​

MemberTypeDescription
modeReadonly<Ref<OokoThemeMode, OokoThemeMode>>Readonly user preference.
resolvedThemeComputedRef<OokoTheme | undefined>Effective client theme, unresolved before mounting.
setMode(mode: OokoThemeMode) => voidApplies and persists a theme preference.
TypeDefinition
OokoThemetype OokoTheme = "light" | "dark";
OokoThemeModetype OokoThemeMode = OokoTheme | "system";
UseOokoThemeReturninterface UseOokoThemeReturn { /** Readonly user preference. */ mode: Readonly<Ref<OokoThemeMode>>; /** Effective client theme, unresolved before mounting. */ resolvedTheme: ComputedRef<OokoTheme | undefined>; /** Applies and persists a theme preference. */ setMode: (mode: OokoThemeMode) => void; }

light and dark are stored under the ooko-theme local-storage key. system removes both the stored value and data-ooko-theme, allowing CSS to follow future system changes.

SSR and hydration ​

The composable does not access window, document, localStorage, or matchMedia while its module loads or while Vue renders on the server. Before the component mounts:

  • mode is system;
  • resolvedTheme is undefined;
  • no document attribute or browser listener is changed.

Do not use resolvedTheme to produce different server markup without an explicit stable fallback. Use CSS for theme-dependent presentation so server and client markup remain identical.

The system theme is correct before Vue mounts because CSS owns automatic selection. A persisted explicit override is applied when the composable mounts; applications that require a zero-flash stored override need a separate early bootstrap strategy compatible with their SSR and Content Security Policy setup.