Switch Pro controller test, swap and all

Nintendo labels, canonical indices — which means the button marked A lights up index 1, and that is the whole reason this page exists. If you have tested a Pro Controller elsewhere and concluded the buttons were mapped wrongly, the behaviour is deliberate, documented in the browser's own source, and correct.

No controller yetLabels shown for Switch Pro

Press any button on your controller

A connected pad stays invisible to this page until you use it. That is the specification working as designed, not a fault — see the note below the tool.

Device report

id
waiting for input
mapping
—
index
—
buttons
—
axes
—
vibrationActuator
—

Vibration

Buttons

  • [0] B—
  • [1] A—
  • [2] Y—
  • [3] X—
  • [4] L—
  • [5] R—
  • [6] ZL—
  • [7] ZR—
  • [8] Minus −—
  • [9] Plus +—
  • [10] Left stick click—
  • [11] Right stick click—
  • [12] D-pad ↑—
  • [13] D-pad ↓—
  • [14] D-pad ←—
  • [15] D-pad →—
  • [16] HOME—

Axes

  • [0] left stick horizontal0.000
  • [1] left stick vertical0.000
  • [2] right stick horizontal0.000
  • [3] right stick vertical0.000

The swap, stated exactly

Nintendo arranges its face-button letters in the mirror of Microsoft's. Because the Gamepad API numbers positions rather than letters, the index follows the place and the letter moves. On a Pro Controller the button marked A is buttons[1] where an Xbox pad has B; the button marked B is buttons[0] where an Xbox pad has A. X and Y swap the same way.

The four face indices only. The Position column is the specification's own wording, quoted; the letters are what each manufacturer prints at that position.
IndexPosition, per the specificationSwitch ProXboxPlayStation
buttons[0] Bottom button in right cluster B A Cross ✕
buttons[1] Right button in right cluster A B Circle ○
buttons[2] Left button in right cluster Y X Square □
buttons[3] Top button in right cluster X Y Triangle △

Across all 17 canonical indices, a Pro Controller and an Xbox pad print the same thing at exactly 4 of them — and all 4 are the d-pad directions, where an arrow is an arrow on both. Every other index carries a different label. That is the strongest possible argument against printing a button letter from an index without first checking which controller you are holding.

The browser's source says so outright

This is unusually well evidenced for a mapping question, because Chromium decodes Switch controllers with dedicated code rather than a generic remap — so instead of shuffling anonymous raw indices, its source assigns canonical positions from named fields. The function is UpdateGamepadFromControllerData in nintendo_controller.cc, and these are its assignments for the face cluster.

Transcribed from Chromium's nintendo_controller.cc. The comment column is Chromium's own, copied from the neighbouring array literal — not our gloss.
Canonical indexAssigned fromChromium's comment
buttons[0] data.button_b // B button
buttons[1] data.button_a // A button
buttons[2] data.button_y // Y button
buttons[3] data.button_x // X button

Read the first row: canonical index 0 — the bottom button of the right cluster — is filled from the controller's B field, and the browser's own comment on the matching entry says "// B button". There is no ambiguity to resolve and no bug to report. A game that prints "press A" for buttons[0] is simply wrong on this hardware, and the fix belongs in the game.

What to check on a Pro Controller specifically

  1. All four face buttons, naming them out loud as you press so the swap does not confuse the result: press A and expect index 1 to light.
  2. D-pad, all four directions. These are the 4 indices that agree with every other pad.
  3. L, R, ZL, ZR. Note that ZL and ZR sit at the canonical trigger positions but are digital switches on this controller — the value jumps straight across with no sweep, which is correct here and would be a fault on an Xbox pad. Compare with the analog trigger test if you are unsure what a sweep looks like.
  4. Minus, Plus, HOME and Capture. Capture appears at index 17, in the extras row, past the canonical 17.
  5. Both stick clicks, then both sticks at rest for a minute on the drift meter.

Why ZL and ZR behave unlike Xbox triggers

On an Xbox or PlayStation pad, canonical indices 6 and 7 are analog: the value climbs continuously as you squeeze, and the pressed flag flips somewhere along the way. The Pro Controller's ZL and ZR occupy the same canonical positions but are switches, so the value goes from 0 to 1 with nothing in between. Neither behaviour is a fault; the canonical layout describes where an input is, not what kind of sensor sits behind it. This is exactly why code should tolerate either answer at those indices and never assume a continuous value is available.

If the controller does not appear at all

Press a button first — a connected pad is invisible to the page until you use one, by design. If it still does not appear, the most productive next step is to change the connection: Chromium's handling of Switch controllers differs by path, including whether a device is presented as one composite pad or as separate halves. Compare the button count and the id string in the device panel between USB and Bluetooth before concluding anything about the hardware, and check the same pad in a second browser to separate a device-table gap from a real fault.

Questions people actually ask

Why does pressing A light up the wrong button on the diagram?

It is not the wrong button — it is the right position. The Gamepad API numbers places on a controller, not letters. Nintendo prints A on the right of the face cluster where Microsoft prints B, so the button marked A is buttons[1] on a Pro Controller and buttons[0] on an Xbox pad. Everything is behaving correctly; the letters simply moved.

Is this a browser bug that will be fixed?

No, and it should not be. Mapping by position is what makes the canonical layout useful: a game that reads the bottom face button gets the bottom face button on every controller, whatever is printed on it. Chromium implements this deliberately — its Nintendo code assigns the primary canonical index from the controller's B field, with a comment saying so. Fixing it by letter would break every game that binds by position.

Where is the Capture button?

At index 17, appended after the canonical set, under the name SWITCH_PRO_BUTTON_CAPTURE in Chromium's source. The Standard Gamepad stops at 16, so any button a controller adds beyond it lands at 17 — which is also where a DualSense puts its touchpad click, and where the macOS and Linux mappers put an Xbox Series X|S Share button. Index 17 alone therefore does not identify a button; you need the controller's id too.

Do Joy-Cons work here?

Often, and each one deserves its own separate run, because each is its own device with its own sticks and buttons. Held sideways, a single Joy-Con's stick axes are rotated relative to the way the browser reports them, so expect the on-screen stick to move at ninety degrees to your thumb. That is a consequence of orientation, not a fault.

Does rumble work on a Pro Controller in a browser?

It depends on the connection and the driver, so press the button and see. The tool reports exactly what the browser said: the effect either resolves, or it reports that no vibration actuator is exposed, or it reports the rejection message. The Pro Controller's HD Rumble is considerably more capable than the fixed-duration dual-rumble effect the specification defines, so a successful test confirms the channel works; it says nothing about the full haptic range.

Should I connect over USB or Bluetooth?

Try both and compare the device panel. Chromium handles Switch controllers through its own dedicated decoding code, and the path a controller takes can differ by connection — including whether it is treated as one composite device or as separate halves. If one connection reports a sensible button count and the other does not, that difference is real and worth knowing before you blame the hardware.

Keep testing

Test the rest of the desk