| Component name | color_scheme |
|---|---|
| In the visitorId | no (reported, kept out of both ids) |
| structuredId group | none |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 11 |
| Collector revision | 1 (reported as revision with every result) |
Most systems let people choose a light or a dark look, and browsers pass that choice to web pages so they can match it. WhiskerJS records light or dark.
What it reads
The CSS prefers-color-scheme media feature through window.matchMedia().
How the technique works
| Order | Query | Value reported |
|---|---|---|
| 1 | (prefers-color-scheme: dark) |
dark |
| 2 | (prefers-color-scheme: light) |
light |
The first match is reported; no match gives unavailable with no_match.
Why it helps
On its own it splits users into two large groups, so it says little. For your server it is context: a result whose other preference signals and colour scheme suddenly change together points to a settings change rather than a different device.
Stability
Low. Users switch themes, and many operating systems switch automatically between day and night. That is why it is outside both ids and is not expected to join them. Added in library PR #29 (2026-10-27) at signalsVersion 11: it is outside both ids, so adding it changed no id and needed no version bump.
Browser support and what blocks it
Every current engine answers the query. In the hosted CI runs of PR #29 every headless browser reported light in every collection. Firefox with resistFingerprinting may report light whatever the system setting is. No browser class excludes it.
Privacy
A theme preference is a low-risk setting, but it is a setting of the user. Leave it out with collect({ exclude: ['color_scheme'] }) if you do not need it; no id changes.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
light or dark |
|
unavailable |
no_api |
no matchMedia |
unavailable |
no_match |
neither query matched |
blocked |
threw, security_error |
matchMedia throws |
excluded |
caller_excluded |
you excluded it |
timed_out |
timeout, aborted |
budget or abort |
Example value
"color_scheme": { "status": "ok", "value": "dark", "hashed": false, "durationMs": 0.1, "revision": 1 }
Questions and answers
Why is the colour scheme not in the visitorId?
Many people switch between light and dark mode, and many systems switch automatically at sunset. An id built on it would change with the time of day.
What does WhiskerJS report when no preference is set?
Browsers report light when the user has not chosen dark, so the value is light or dark; unavailable with no_match is only expected in very old engines.