Keyboard layout fingerprinting reads getLayoutMap() to see your physical key layout — a silent, Chromium-only signal that hints at locale and barely changes.
Keyboard layout fingerprinting reads a signal most people never think about: the physical layout your keyboard is configured to use, exposed through the getLayoutMap() method of the Keyboard API. A website can ask, in effect, "what character does this physical key produce?" — and the answer reveals your OS-level layout (QWERTY, AZERTY, QWERTZ, JIS, and dozens more) without ever asking permission. This guide explains how the API works, why the physical layout leaks locale and region, and what actually limits its usefulness as a tracking signal.
Key Takeaways
navigator.keyboard.getLayoutMap()returns a map from physical key codes (like"KeyQ") to the character your layout produces at that position ("q"on QWERTY,"a"on AZERTY).- The physical layout correlates with locale and region — AZERTY is common in France, QWERTZ in Germany/Austria/Switzerland, JIS in Japan — adding a signal independent of
navigator.languageor timezone. - The API is implemented only in desktop Chromium-based browsers (Chrome 69 and later, Edge, Opera); Firefox and Safari don't expose it at all, and the specification itself expects mobile devices not to support it — so it's unusable against a large share of visitors.
- It shows no permission dialog to the user; it's gated only by requiring a secure (HTTPS) context and by the
keyboard-mapPermissions Policy feature, which defaults toself— a site-controlled restriction, which is a very different thing from user consent. - Because changing a system keyboard layout is a deliberate, rare action, the value is unusually stable across sessions compared to signals like screen resolution or window size.
What is keyboard layout fingerprinting?
Keyboard layout fingerprinting is the practice of using the Keyboard API to determine which physical key layout your operating system is currently using, and folding that value into a device or browser identifier. It's a small, single API call, but it adds a signal that other fingerprinting techniques don't cover: most fingerprint suites read rendering hardware (canvas, WebGL), installed software (fonts), or reported preferences (navigator.language, timezone) — none of which directly reflect how your physical keyboard is wired to your OS.
Unlike font or canvas fingerprinting, this technique isn't about inference through rendering differences. getLayoutMap() is a purpose-built API that returns the layout information directly, which is what makes it worth understanding on its own.
Inside getLayoutMap(): what it returns
getLayoutMap() returns a Promise that resolves to a KeyboardLayoutMap — a read-only, Map-like object. Its keys are physical key codes, drawn from the standard code values that identify a key by its position on the keyboard regardless of what's printed on the keycap ("KeyQ" is always the key just right of Tab, no matter the layout). Its values are the character your currently configured layout produces at that position.
// Read the character each physical key produces under the current layout
async function getKeyboardLayoutSignal() {
if (!navigator.keyboard?.getLayoutMap) return null; // Firefox, Safari: unsupported
const layoutMap = await navigator.keyboard.getLayoutMap();
const probeCodes = ['KeyQ', 'KeyW', 'KeyA', 'KeyY', 'KeyZ', 'Semicolon', 'BracketLeft'];
// On QWERTY: KeyQ -> "q". On AZERTY: KeyQ -> "a", KeyW -> "z", KeyA -> "q".
return probeCodes.map((code) => layoutMap.get(code) ?? null).join(',');
}
The distinction between a code (physical position) and a key (the character produced) is exactly what makes this fingerprintable: two visitors with identical hardware and identical browser versions can return different strings from the same probe, purely because their OS keyboard layout setting differs. Probing a handful of codes that vary the most across common layouts (the letters that move between QWERTY, AZERTY, and QWERTZ) is enough to bucket a visitor into a specific layout family with very little code.
Why physical layout leaks locale and region
Keyboard layouts are not evenly distributed — they cluster tightly by country and language community:
- QWERTY dominates the US, UK, and most English-speaking regions (with a UK variant that swaps a few punctuation keys).
- AZERTY is the default in France and Belgium.
- QWERTZ is standard across Germany, Austria, and Switzerland.
- JIS layouts are specific to Japan; ЙЦУКЕН to Russia and other Cyrillic-script countries.
That clustering is what makes the signal valuable to a tracker: it's a proxy for region that's independent of IP-based geolocation and independent of the Accept-Language header or navigator.language, both of which a privacy-conscious user might already override. A visitor claiming a US IP and English navigator.language but reporting an AZERTY layout is an inconsistency worth flagging — the same logic our fingerprint consistency checklist applies to GPU/OS mismatches applies here to language/layout mismatches. On its own, layout is a coarse, low-entropy signal — there are only a few dozen common layouts worldwide — but combined with other attributes it narrows the crowd a visitor blends into.
Browser support and the permission model
The practical reach of this technique is limited by where the API actually exists:
| Browser | getLayoutMap() support | User-facing prompt |
|---|---|---|
| Chrome / Edge / Opera, desktop (Chromium) | Yes (Chrome 69+) | None |
| Chromium on mobile | Typically absent, or an empty map | N/A |
| Firefox | Not implemented | N/A |
| Safari | Not implemented | N/A |
Three things stand out. First, this is a Chromium-exclusive signal — a tracking script that relies on it silently gets undefined in Firefox and Safari, so it can only ever fingerprint part of the web's traffic.
Second, its reach is narrower still on phones. The WICG keyboard-map specification says outright that because mobile devices don't commonly have physical keyboards, the API "will not typically be present or supported on mobile devices," and that a mobile platform which does implement it may return a layout map containing no entries. For a mobile-heavy audience, that removes most of the population this technique could otherwise bucket — which is a large part of why it stays a supplementary signal rather than a core one.
Third, where it is supported, there is no consent dialog like the ones camera, microphone, or geolocation access trigger. The API only requires a secure (HTTPS) context and permission from the keyboard-map Permissions Policy feature, whose default allowlist is self. That default is worth reading carefully: a first-party script on the page can call it freely, while a cross-origin <iframe> gets a SecurityError unless the embedding page explicitly grants it with allow="keyboard-map". So it's a boundary site operators control between themselves and their embeds, not something that asks the visitor for anything. From the user's point of view, the call is silent: no icon, no prompt, no way to notice it happened. The related keyboard.lock() method, by contrast, is scoped to fullscreen sessions and games — a different feature with a different threat model, not a gate on getLayoutMap(). The API is still tracked as an experimental, non-Baseline feature, which is exactly why cross-browser support hasn't broadened.
Stability: why this signal barely changes
Most fingerprint attributes drift: you plug in a second monitor and your screen resolution changes, you install a font and your font list grows, a browser update tweaks a User-Agent string. Keyboard layout is unusually static by comparison. Changing the OS-level layout requires opening system settings and deliberately switching it — something the overwhelming majority of users never do, because it's tied to the physical keyboard they use every day. That stability is what makes it attractive as a supplementary signal for tracking: even if a script only checks it occasionally, the value it recorded last month is still almost certainly correct today, unlike canvas noise a privacy browser might rotate every session.
How it fits the bigger picture
Keyboard layout fingerprinting is a minor contributor next to canvas, WebGL, or font fingerprinting, but it illustrates a pattern worth recognizing: browsers keep exposing narrow, purpose-built APIs (media devices, speech-synthesis voices, network information) that leak a sliver of device or locale data each, with no permission prompt of their own. None of them is decisive alone; stacked together, they compound. Our browser fingerprinting guide covers how these signals combine, and the font fingerprinting technique is a close cousin — both target Chromium and other browsers with no visible request, and both are strongest as one input among many rather than a standalone identifier.
Mitigation
- Use a browser that doesn't implement the API. Firefox and Safari simply don't ship
getLayoutMap(), so visitors on those browsers are unaffected by this specific technique regardless of any other setting. - On Chromium, cut down what scripts can silently reach. An extension that blocks third-party tracking scripts before they execute removes the call site altogether — but be selective, since a broad-access extension is itself a tracking vector; see browser extension privacy risks before installing one. If you run a site rather than just visit one,
Permissions-Policy: keyboard-map=()switches the feature off for your page and everything embedded in it. - Don't rely on hiding your language settings alone. Spoofing
navigator.languageor your IP's apparent region while leaving your real keyboard layout in place creates the exact inconsistency this signal is good at catching — uniformity across all your signals matters more than hiding any single one. - Know the limits. Like font and canvas fingerprinting, this is a rendering/API-level signal, not stored data — private/incognito mode does not change it, because there's nothing to clear.
Frequently Asked Questions
Does keyboard layout fingerprinting need any permission?
No. getLayoutMap() requires only a secure (HTTPS) context and the keyboard-map Permissions Policy feature, which is allowed for the page's own origin by default and can be switched off by the site's own header — neither of which shows the visitor a consent dialog. It's silent by design.
Which browsers can be fingerprinted this way?
Desktop Chromium-based browsers — Chrome (since version 69), Edge, Opera, and others built on the same engine. Firefox and Safari have not implemented getLayoutMap(), so the technique doesn't apply to their users at all, and the specification expects mobile devices not to support it either.
Is my keyboard layout the same as my typing language?
Not necessarily. Layout is a system-level setting tied to your physical keyboard; you can type in a given language using a different layout than the one "native" to that language's country, though most people don't. That's exactly why layout is a useful additional signal rather than a duplicate of navigator.language.
Can this alone identify me?
No — there are only a few dozen common layouts worldwide, so it's a low-entropy signal on its own. It becomes meaningful only when combined with other fingerprint attributes, or when it contradicts your other reported locale signals.
How can I check what my browser exposes?
Run BrowserInsight's fingerprint check to see the full set of signals your browser leaks, including how the values you report line up with each other.
Conclusion
Keyboard layout fingerprinting is a small, quiet API call that turns a system setting almost nobody thinks about into a locale-correlated, no-permission signal — one that's unusually stable because changing it takes deliberate effort. It's confined to desktop Chromium browsers and carries low entropy on its own, but it's a clean example of how narrow, purpose-built browser APIs keep adding up: each one leaks a little, none of them ask, and together they narrow the crowd a visitor blends into.
Want to see the stack rather than the single signal? Run the free fingerprint check — it reads the attributes your browser hands out and shows you where they agree with each other and where they don't.
Recommended Reading:


