PathLogs UI
Русский

Hooks

useTheme

The current theme as external DOM state, with no flash on load.

The current theme as external DOM state. The hook does not store the theme itself — it reads the data-theme attribute on <html>, so a theme change from anywhere in the app reaches everyone at once.

Example

Выбор пользователя
dark
Что на экране
dark

Меняется тема всего сайта — состояние живёт в атрибуте на <html>, а не внутри компонента.

A ready-made switch already exists — ThemeToggle from @toimetdev/pathlogs-core. The hook is for when the switch is your own, or the theme feeds into logic: the colour of a chart, say.

What it returns

preference"light" | "dark" | "system"

What the user chose.

resolved"light" | "dark"

«system» already resolved into what is actually on screen.

setTheme(theme: ThemePreference) => void

Applies the theme and remembers the choice.

toggle() => void

Switches between light and dark. «system» resolves to the opposite of the current one.

The only argument is the localStorage key ("theme" by default). It must match the key passed to themeScript().

The flash on load

The theme has to be applied before the first paint, or the page flashes. That is what the tiny synchronous script in <head> is for:

tsx
import { themeScript } from "@toimetdev/pathlogs-tokens";

<html lang="en" suppressHydrationWarning>
  <head>
    <script dangerouslySetInnerHTML={{ __html: themeScript() }} />
  </head>
</html>

The subscription watches both the attribute and the system setting; the latter only matters while system is selected.

Without React

The same operations are available as plain functions — called by the inline script and by the tests alike:

tsx
import {
  getThemePreference,
  getResolvedTheme,
  setThemePreference,
  toggleTheme,
  subscribeTheme,
  themeScript,
} from "@toimetdev/pathlogs-tokens";

Writing to localStorage can fail (private mode, cookies disabled) — and that does not break the switch: the theme is applied regardless, it just will not survive a reload.