A single-purpose static page that shows what a browser can — and cannot — learn about the displays attached to your machine. It runs the same check a remote interview or online proctoring page can run, so you can see your own setup the way those pages see it.
Live: https://autocue-interview-tools.github.io/detect-screen/
Nothing is uploaded. The page is static, has no analytics and no cookies, and makes no network requests after it loads.
| Verdict | Meaning |
|---|---|
| Single display | One logical screen (on macOS this may also be a mirrored set) |
| Extended | Two or more screens, each at its own position in the desktop |
| Mirrored | Two or more screens at an identical position and size |
| Mixed | Three or more screens where one pair duplicates and another extends |
| Permission needed | Window Management was declined |
| Not supported | Browser exposes neither reading (Firefox, Safari) |
Beyond the verdict it draws the virtual desktop to scale — including where the browser window sits — and lists each screen's position, size, available area, scale factor, colour depth and role.
Two browser readings, both Chromium-only:
screen.isExtended— a boolean, no permission required. True when the desktop spans more than one display.getScreenDetails()— after the Window Management permission is granted, returns a liveScreenDetailsobject with every screen's bounds, scale, label and flags.
Mirroring is inferred from geometry: screens reported at an identical left, top, width, height are duplicating each other, because extended screens never overlap exactly.
Changes arrive through the screenschange, currentscreenchange and per-screen change
events, with a 400 ms poll as a backstop for window moves that fire no event.
macOS merges a mirrored set into one logical screen before Chrome sees it, so mirroring is undetectable there — the page says so rather than guessing.
Twelve fully translated static pages, each with its own metadata, canonical URL and
hreflang alternates:
English · Español · 简体中文 · हिन्दी · العربية (RTL) · Português · Русский · 日本語 · Deutsch · Français · 한국어 · Bahasa Indonesia
Pages are generated from one template and one JSON file per language.
node build.mjs # writes index.html, <lang>/index.html, sitemap.xml, robots.txt, 404.html
node verify.mjs # structural checks: hreflang, canonical, JSON-LD, i18n key coverage
To change copy, edit i18n/<code>.json and rebuild — never edit the generated HTML.
To add a language, add i18n/<code>.json and append its code to ORDER in build.mjs;
verify.mjs fails if a translation file is not listed.
The Open Graph image is rendered from src/og.html:
chrome --headless --screenshot=assets/og.png --window-size=1200,630 src/og.html
build.mjs generator
verify.mjs post-build checks
i18n/*.json one file per language: metadata, page copy, runtime strings
assets/style.css shared stylesheet
assets/app.js detection logic, reads window.__I18N__ for its strings
src/og.html source of the social card
MIT