Hardware & Capabilities · Browser Tests

Gamepad Test

Detect connected controllers and read their buttons and axes live, using the Gamepad API.

Waiting for a controller…
Press a button on your controller

Browsers hide gamepads until you interact with one, so the list stays empty until you press a button or move a stick. Connect the controller first if you have not already.

On this page
  1. What the Gamepad API can see
  2. Why the list starts empty
  3. Standard and raw layouts
  4. How the live read-out works
  5. Why one pad behaves differently
  6. What it does and does not reveal

What the Gamepad API can see

The Gamepad API lets a web page read controllers connected to your machine. A call to navigator.getGamepads() returns a list, one entry per pad the browser knows about, and each entry is a snapshot of its current state.

  • id is a string naming the device, usually the vendor and product, for example a Xbox or DualSense identifier.
  • mapping is either standard or empty, and it says whether the button order follows the W3C layout.
  • buttons is an array, each item carrying a pressed flag, a touched flag and an analogue value from 0 to 1.
  • axes is an array of floats from -1 to 1 for sticks and sometimes triggers.
  • timestamp marks when the snapshot was taken, and connected says whether the pad is still present.

The panel above reads all of it and shows the counts, the layout and a live view of the input.

Why the list starts empty

If you loaded this page and saw the waiting message, that is the intended behaviour rather than a failure. Browsers deliberately conceal gamepads until the user does something with one, so that a page cannot silently inventory the hardware attached to your machine. The first button press or stick movement both reveals the pad and fires the gamepadconnected event.

The same rule applies in reverse. If a wireless controller sleeps or is unplugged, it disappears from the list and a gamepaddisconnected event fires. The panel watches for both events and switches between the waiting state and the read-out as the list changes, so you can leave it open while you connect and disconnect a pad.

A gesture is required by design

No amount of code can read a controller before the user touches it. If a page ever claims to have detected your gamepad without that interaction, it is guessing from something else.

Standard and raw layouts

The mapping field is the difference between code that works anywhere and code that needs a lookup table. When it reads standard, the browser has already normalised the pad to the W3C layout: button 0 is the bottom face button, 1 is right, 2 is left, 3 is top, and the shoulder, trigger and menu buttons follow a fixed order.

When the field is empty, the device is reporting its own arrangement. The counts still work, so the panel can tell you how many buttons and axes exist, but the meaning of each index depends on the controller. That is why a game written for standard pads may behave oddly with an unusual or older device. The panel labels the mapping for each entry so you can see which situation you are in.

How the live read-out works

The Gamepad API has no input events. There is no buttonpressed callback; a page has to ask for the current state on a loop, and the natural loop is requestAnimationFrame, which runs once per repaint, so a 60 Hz display is polled about sixty times a second.

The panel does exactly that. Each frame it takes a fresh snapshot, and rebuilds the pressed-button chips only when the set of pressed buttons changes, so the page is not rewriting the DOM sixty times a second for nothing. The axis rows are updated in place, because a stick moves continuously and its value changes on almost every frame. Polling stops costing anything noticeable when no controller is present, since the loop simply checks an empty list and waits for the next frame.

Why one pad behaves differently in each browser

Three things decide what this API reports, and they rarely line up. The first is the operating system’s driver: Windows reads an Xbox pad through XInput, while a PlayStation pad over Bluetooth may present as a generic HID device until a driver is installed. The second is the browser’s own input backend, so the same physical controller can report a standard mapping in Chrome and a raw layout in Firefox.

The third is context. The API is only exposed in a secure context, so it works over HTTPS and not on an insecure page, and mobile support is patchy, particularly on iOS. Rumble is separate again: where a pad exposes a GamepadHapticActuator, a site can call playEffect to vibrate it, but this page never does. The device and hardware test covers the rest of what a page can learn about attached hardware.

What it does and does not reveal

The controller id is the only genuinely identifying value here, and it is narrow: it is readable only while a pad is connected and has been used, and it is shared by everyone with the same model. On a desktop with no controller attached, the API returns an empty list and reveals nothing at all. That is a much smaller footprint than the sensors in the device and hardware test or the touch signals in the touch support test.

This page reads input and shows it, and goes no further. It never triggers rumble or vibration, even on pads that support it, because that would be a side effect you did not ask for. Nothing is recorded, nothing is uploaded, and the read-out is gone the moment you close the tab. For the wider picture of what a page can detect about your machine, try the browser information test.

Frequently Asked Questions

Why does the page say no controller is connected?
Browsers deliberately hide gamepads until you interact with one. The list from navigator.getGamepads() stays empty, and the gamepadconnected event does not fire, until you press a button or move a stick on the controller. Press something once and the read-out above will appear. This is a privacy measure rather than a fault, and it applies to every site, not just this one.
How many controllers can I test at once?
The API reports every pad the browser has seen, indexed from 0, though the specification only guarantees the first four slots and some browsers expose exactly that many. In practice most machines report one or two. The read-out above lists all of them and reads buttons and axes from the first. Wireless pads that go to sleep may drop off the list until you press a button to wake them again.
What is the difference between standard and raw mapping?
A controller with mapping set to standard follows the W3C layout, so button 0 is always the bottom face button regardless of the make. A raw layout reports whatever order the device uses, and a page must map the indices itself. Most modern Xbox, PlayStation and generic pads report standard, but the same pad can report raw in one browser and standard in another, which is why games sometimes need a per-browser fix.
Why are the trigger values sometimes decimal rather than just pressed?
Analogue buttons carry a value between 0 and 1 alongside the pressed flag. A trigger pulled halfway reports something like 0.5, which is why the live buttons above show a number for analogue inputs and nothing for a plain digital button. Sticks behave the same way, except their axes run from -1 to 1 and sit near zero when they are untouched.
Can a website identify me from my controller?
The id string often contains the vendor and product name, and it is only readable when a controller is connected and has been used, so on a desktop with nothing plugged in it reveals nothing. That makes it a narrow but real signal, contributing a few bits on top of everything else. The fingerprint test shows how such details combine.