JavaScript Vibration API
The Vibration API is a web technology that allows web developers to provide haptic feedback to users through their devices, such as smartphones and tablets.
Introduction to the Vibration API
The Vibration API lets web pages make a device's vibration motor buzz, giving users haptic (touch-based) feedback. It is intended for mobile phones and tablets that physically vibrate — on a desktop with no motor, the calls succeed silently and do nothing.
The entire API is a single method, navigator.vibrate(). There is no permission prompt and no event to listen for: you call it, and the device vibrates. The trade-off is that browsers restrict when you may call it, which this chapter explains in detail.
This page covers the method's two argument forms, how to stop a buzz, feature detection, the user-gesture and mobile-only limitations, and how to use vibration tastefully.
The navigator.vibrate() method
navigator.vibrate() accepts one of two argument types:
- A single number — vibrate once for that many milliseconds.
- An array of numbers — a pattern of alternating vibrate / pause durations.
It returns a boolean: true if the request was accepted, false if it was rejected (for example, when no user gesture has occurred). On devices without a motor the method still returns true but produces no buzz.
// Single vibration for 500 milliseconds
navigator.vibrate(500);Vibration patterns
When you pass an array, the numbers are read as vibrate, pause, vibrate, pause, …. Odd-indexed entries are silent gaps.
// Vibrate 200 ms, pause 100 ms, vibrate 400 ms
navigator.vibrate([200, 100, 400]);
// "Morse"-like triple buzz: buzz, gap, buzz, gap, buzz
navigator.vibrate([100, 50, 100, 50, 100]);A trailing pause has no effect, since there is nothing after it to vibrate.
Stopping a vibration
A new call replaces any vibration already in progress. To cancel one outright, pass 0 or an empty array:
navigator.vibrate(0); // stop immediately
navigator.vibrate([]); // also stops — equivalent to 0This is handy for resetting feedback when a user dismisses an alert or navigates away.
Feature detection
navigator.vibrate is undefined in unsupported browsers, so calling it directly would throw. Guard every call:
function buzz(pattern) {
if ('vibrate' in navigator) {
return navigator.vibrate(pattern);
}
return false; // API not available — fall back to a visual cue
}
buzz(200);
buzz([100, 50, 100]);You can run the detection itself anywhere — including Node or a desktop browser — even though the actual vibration only happens on supporting hardware.
Practical Applications
Understanding how to incorporate the Vibration API effectively into web applications can significantly enhance user engagement and satisfaction. Below are examples of practical applications that illustrate the versatility of the Vibration API.
Feedback on user actions
A short buzz confirms a tap on devices where the user can't always see the screen react. Note that the click handler itself is the user gesture, so the call is allowed:
document.getElementById('button').addEventListener('click', () => {
if ('vibrate' in navigator) {
navigator.vibrate(100); // brief confirmation buzz
}
});Notification alerts
When a sound or visual cue might be missed or inappropriate (silent mode, accessibility), a distinctive pattern can stand in for it:
function alertUser() {
if ('vibrate' in navigator) {
navigator.vibrate([500, 200, 500]); // buzz, pause, buzz
}
}Enhancing gaming experiences
In web games, vibration adds physical feedback at key moments — but only if the moment follows recent user input, or the call will be ignored:
function gameOver() {
if ('vibrate' in navigator) {
navigator.vibrate(1000); // one long buzz signals game over
}
}Limitations you must plan for
The Vibration API looks trivial, but browsers wrap it in restrictions that quietly cause it to "do nothing":
- Mobile-only in practice. Vibration requires a hardware motor. Desktop browsers either lack the method entirely (Safari, Firefox on desktop) or accept the call without buzzing. Treat vibration as an enhancement, never the only feedback.
- Requires a user gesture. Modern browsers ignore
navigator.vibrate()unless it runs in response to a real interaction (a tap, click, or key press). A buzz fired on page load, from asetTimeout, or from a background event is silently dropped — the method returnsfalse. Trigger vibration directly inside an event handler. - No permission, no feedback channel. There is no prompt and no error event; a rejected call simply returns
false. Check that return value if you need to know whether it worked. - Hidden tabs are blocked. If the page is not visible (backgrounded tab), the request is ignored.
- Patterns are capped. Browsers limit the maximum total duration and the number of entries in a pattern; extremely long buzzes are truncated.
Best Practices and Considerations
While the Vibration API opens new avenues for user engagement, its implementation should be approached with consideration for the user experience.
- Respect User Preferences: Always provide an option for users to disable vibration feedback, catering to those who may find it intrusive or have accessibility concerns.
- Battery Consumption: Be mindful of the potential impact on device battery life, particularly with extensive use of patterns or long vibrations.
- Test on Multiple Devices: Vibration intensity and pattern perception can vary significantly across devices. Testing on various devices ensures a consistent user experience.
- Browser Compatibility: The Vibration API is primarily supported on mobile browsers (Chrome, Firefox, Edge). It is not supported in Safari or most desktop browsers. Always verify support before implementation.
Conclusion
JavaScript's Vibration API offers a practical way to engage users through tactile feedback with a single method, navigator.vibrate(). Remember the essentials: feature-detect before calling, trigger only from user gestures, keep it mobile-first, and always pair haptics with a visual or audio fallback so nothing is lost on unsupported devices.
To keep exploring device-aware browser APIs, see the Screen Orientation API for reacting to portrait/landscape changes, the Geolocation API for location data, and Browser Environment, Specs for how the navigator and other host objects fit together.