WebHID is a browser API that lets a web page exchange reports with a Human Interface Device, such as a game controller, macro pad or custom button box. HID stands for Human Interface Device, the USB class used by keyboards and mice. WebHID is a Web Platform Incubator Community Group draft, not a W3C Recommendation, and it is exposed as navigator.hid in secure contexts only.
A page cannot enumerate every HID device. It calls navigator.hid.requestDevice() with a list of filters, and the browser shows a chooser. The call needs transient activation, such as a click. Without it the promise rejects with a SecurityError. The result is an array of HIDDevice objects, because one chosen item can represent several HID interfaces and the browser must then grant all of them.
Each filter can contain four fields: vendorId, productId, usagePage and usage. The spec also defines exclusionFilters, which remove devices that would otherwise match. Devices the user already approved come back from navigator.hid.getDevices() without a prompt, so a page can reconnect on the next visit.
Talking to a device follows a fixed sequence:
The browser parses the device report descriptor and exposes the result as a collections array, so you can read which usage pages and report IDs a device defines. A usage is a 32-bit value: the usage page sits in the high 16 bits and the usage ID in the low 16 bits. If the interface does not use report IDs, pass 0 as the reportId. If it does, 0 is reserved and must not be used.
const usage = (page, id) => ((page << 16) | id) >>> 0;
const hex = n => "0x" + n.toString(16).padStart(8, "0");
const filter = { vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 };
console.log("filter vendorId:", filter.vendorId, "=", "0x" + filter.vendorId.toString(16));
console.log("consumer control usage:", hex(usage(0x0c, 0x01)));
console.log("keyboard usage:", hex(usage(0x01, 0x06)));
const sendReportId = (usesReportIds, id) => usesReportIds ? (id === 0 ? "reserved, do not use 0" : "report " + id) : "pass 0";
console.log(sendReportId(false, 0), "|", sendReportId(true, 0), "|", sendReportId(true, 2));
Output:
filter vendorId: 43981 = 0xabcd
consumer control usage: 0x000c0001
keyboard usage: 0x00010006
pass 0 | reserved, do not use 0 | report 2
WebHID works in Chrome and Edge 89 and later and in Opera 76 and later. MDN compatibility data lists no support in Firefox or Safari, and it flags the API as experimental. Feature-detect with "hid" in navigator before showing any connect button.
Yes, the spec relies on a blocklist file kept in the WICG webhid repository to restrict which devices a site can reach. It also notes that a browser can deny keyboard-like devices by checking for a top-level collection that uses the keyboard usage. Do not build a feature that depends on reaching a standard keyboard.