PointerEvent: persistentDeviceId property

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

The persistentDeviceId read-only property of the PointerEvent interface is a unique identifier for the pointing device generating the PointerEvent. This provides a secure, reliable way to identify multiple pointing devices (such as pens) interacting with the screen simultaneously.

A persistentDeviceId persists for the lifetime of a browsing session. To avoid the risk of fingerprinting/tracking, pointing devices are assigned a new persistentDeviceId at the start of each session.

Pointer events whose generating device could not be identified are assigned a persistentDeviceId value of 0.

Value

An integer, or 0 if the device generating the PointerEvent could not be identified.

Note: Due to digitizer and pointing device hardware constraints, a persistentDeviceId may not be available for all pointer events, particularly with older hardware. For example, the pointing device might not report its hardware ID to the digitizer in time for pointerdown to receive a persistentDeviceId: it may initially be 0 and change to a valid value for later events in the stroke.

Examples

Assign color for each persistentDeviceId

Assuming the following HTML:

html
<canvas id="inking-surface" width="1280" height="720"></canvas>

The following JavaScript assigns a different inking color to up to three unique pointers interacting with a canvas:

js
const colorBlue = 0;
const colorGreen = 1;
const colorYellow = 2;
const colors = [colorBlue, colorGreen, colorYellow];

const pointerToColorMap = new Map();
let colorAssignmentIndex = 0;

const canvas = document.querySelector("#inking-surface");

// Listen for a pointerdown event and map the persistentDeviceId to a color
// if it exists and has not been mapped yet
canvas.addEventListener("pointerdown", (e) => {
  if (e.persistentDeviceId && !pointerToColorMap.has(e.persistentDeviceId)) {
    pointerToColorMap.set(e.persistentDeviceId, colors[colorAssignmentIndex]);

    // Bump the color assignment index and loop back over if needed
    colorAssignmentIndex = (colorAssignmentIndex + 1) % colors.length;
  }
});

// Listen for a `pointermove` and get the color assigned to this pointer
// if persistentDeviceId exists and the pointer has been color mapped
canvas.addEventListener("pointermove", (e) => {
  if (e.persistentDeviceId && pointerToColorMap.has(e.persistentDeviceId)) {
    const pointerColor = pointerToColorMap.get(e.persistentDeviceId);
    // Do some inking on the <canvas>
  }
});

Specifications

Specification
Pointer Events
# dom-pointerevent-persistentdeviceid

Browser compatibility

desktop mobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
persistentDeviceId
Chrome – Full support
Chrome 128 (Release date: 2024-08-20)
footnote Full support
Edge – Full support
Edge 128 (Release date: 2024-08-22)
footnote Full support
Firefox – Full support
Firefox 141 (Release date: 2025-07-22)
footnote Full support
Opera – Full support
Opera 114 (Release date: 2024-09-25)
footnote Full support
Safari – No support
Safari
footnote No support
Chrome Android – Full support
Chrome Android 128 (Release date: 2024-08-20)
footnote Full support
Firefox for Android – Full support
Firefox for Android 141 (Release date: 2025-07-22)
footnote Full support
Opera Android – Full support
Opera Android 85 (Release date: 2024-10-29)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 28 (Release date: 2025-04-02)
footnote Full support
WebView Android – Full support
WebView Android 128 (Release date: 2024-08-20)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support