# Vibration API

> Use navigator.vibrate() for simple tactile feedback, detect support, cancel a pattern, and handle activation, visibility, and platform limits.

The Vibration API provides simple tactile feedback through `navigator.vibrate()`. It accepts one vibration duration or an alternating sequence of vibration and pause durations.

The W3C specification records implementations in Chromium-based browsers, opposition from WebKit, and removal from Firefox 129. It describes the feature as limited availability and does not provide a way to determine whether vibration hardware is present or enabled.

## Where it is supported

The W3C specification records support in Chromium-based browsers, opposition from WebKit, and removal from Firefox 129. Even where the method exists, the API cannot report whether vibration hardware is present or enabled.

## Syntax

```js
navigator.vibrate(duration);
navigator.vibrate([vibrate, pause, vibrate]);
```

The method returns a boolean. For an ordinary web document, the specification returns `false` when the document is not visible, when sticky user activation is absent, or when the implementation declines the request; a `true` return does not establish that the device has vibration hardware. The specification notes that a trusted or privileged application closely integrated with the operating system may ignore the visibility check.

## Parameters

`pattern` is an unsigned duration in milliseconds or a sequence of unsigned durations. Sequence entries alternate between vibration and pause, starting with vibration. The specification truncates a sequence after 10 entries and caps each entry at 10,000 milliseconds.

Passing `0`, an empty array, or an array whose entries are all zero cancels an active pattern.

## Exceptions

`vibrate()` does not define DOM exceptions. For an ordinary web document, a hidden document returns `false`; the specification allows a trusted or privileged application closely integrated with the operating system to ignore that visibility check. An existing pattern is aborted before a new accepted pattern starts. When the top-level document becomes hidden, the user agent must abort the running vibration algorithm.

:::caution
Mozilla bug 1924685 records Firefox 131 on Ubuntu returning `Uncaught TypeError: window.navigator.vibrate is not a function` for `window.navigator.vibrate(500)`. This matches the specification's record that Firefox removed its implementation in version 129.
:::

## Examples

Both examples pair vibration with visible feedback because API presence does not guarantee a physical vibration.

### Confirming an action with a short pulse

Call the method from a user action so the document has sticky activation. The fallback updates visible status instead of treating vibration as the only confirmation.

```html
<label>Draft <textarea id="draft"></textarea></label>
<button id="save" type="button">Save draft</button>
<p id="status" role="status"></p>

<script>
const saveButton = document.querySelector("#save");
const status = document.querySelector("#status");

saveButton.addEventListener("click", () => {
  localStorage.setItem("draft", document.querySelector("#draft").value);
  status.textContent = "Draft saved";

  if ("vibrate" in navigator) {
    navigator.vibrate(80);
  } else {
    status.dataset.haptics = "unavailable";
  }
});
</script>
```

The text update is the fallback branch and remains present even when `vibrate()` exists but the device does not vibrate.

### Starting and cancelling a pattern

Store no timer for cancellation; passing zero asks the API to stop the active pattern.

```html
<button id="start-alert" type="button">Start alert</button>
<button id="stop-alert" type="button">Stop alert</button>
<p id="visual-alert" role="status" hidden>Alert active</p>

<script>
const start = document.querySelector("#start-alert");
const stop = document.querySelector("#stop-alert");
const visualAlert = document.querySelector("#visual-alert");

function showVisualAlert() {
  visualAlert.hidden = false;
}

function hideVisualAlert() {
  visualAlert.hidden = true;
}

start.addEventListener("click", () => {
  showVisualAlert();
  if (!("vibrate" in navigator)) {
    return;
  }

  navigator.vibrate([100, 50, 100]);
});

stop.addEventListener("click", () => {
  if ("vibrate" in navigator) navigator.vibrate(0);
  hideVisualAlert();
});
</script>
```

The visual alert supplies the unsupported path, and the stop action clears both forms of feedback.

## See also

- [User activation](/reference/capabilities/user-activation/), for the sticky activation requirement
- [Notifications API](/reference/notifications/notifications-api/), for system notifications rather than simple tactile feedback
- [Vibration API](https://www.w3.org/TR/vibration/) (w3.org)
- [Navigator: vibrate() method](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate) (developer.mozilla.org)