How to Use the Vibration API to Add Haptic Feedback to Mobile Web Apps

Posted by

Learn how to give your users tactile feedback with a single JavaScript call, no frameworks, no native SDKs.

Learn how to give your users tactile feedback with a single JavaScript call, no frameworks, no native SDKs.

Introduction

Mobile users expect to feel as well as function.
Native apps do this effortlessly: a soft buzz when you send a message, a subtle vibration when something fails.

But what if your web app could do the same?

The good news: it can. The Vibration API lets web apps trigger short bursts of vibration for tactile feedback, perfect for buttons, form submissions, game events, or notifications.

In this post, you’ll learn how to:

  • Trigger device vibrations using JavaScript
  • Design vibration patterns
  • Combine vibrations with other browser APIs
  • Follow best practices for UX and accessibility

Let’s make your mobile web app feel alive.


1. What Is the Vibration API?

The Vibration API provides a way for web apps to access the vibration hardware of supported devices.
It’s available through the navigator.vibrate() method, which takes either:

  • A number (milliseconds of vibration), or
  • An array of numbers (vibration and pause pattern).

Example:

navigator.vibrate(200); // vibrate for 200ms

That single line makes your phone buzz.
 No native code, no libraries, pure JavaScript.


2. Browser Support

Before diving in, know where it works.

To test it properly, use Chrome or Firefox on Android.
Also, the API typically requires:

  • HTTPS context (or localhost)
  • User interaction (e.g., a click event)

3. Basic Vibration Feedback

A simple vibration can make an action feel responsive.

<button id="save">Save</button>

<script>
document.getElementById('save').addEventListener('click', () => {
navigator.vibrate(100); // short feedback buzz
alert('Data saved!');
});
</script>

That tiny vibration bridges the gap between the user’s tap and your app’s reaction, exactly what haptic feedback is meant to do.


4. Creating Vibration Patterns

You can define a pattern of vibration and pauses by passing an array:

navigator.vibrate([200, 100, 200]);

This means:

  • Vibrate for 200ms
  • Pause for 100ms
  • Vibrate again for 200ms

Patterns are great for differentiating actions, for instance, a single buzz for success, a triple buzz for error.

Example: Success and Error Feedback

function vibrateSuccess() {
navigator.vibrate(150);
}

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

Call the appropriate one after an API call or form validation.


5. Real-World Use Cases

a. Confirming User Actions

Give instant feedback when buttons are pressed.

button.addEventListener('click', () => navigator.vibrate(50));

b. Form Submission

Buzz once when the form submits, or in a pattern when validation fails.

if (isValid) navigator.vibrate(100);
else navigator.vibrate([100, 50, 100]);

c. Game Events

Simulate hits, crashes, or item pickups.

player.onHit = () => navigator.vibrate([200, 100, 200]);

d. Notifications

Pair a vibration pattern with the Notifications API.

new Notification('New Message!');
navigator.vibrate([200, 100, 200]);

These tactile cues make your app feel dynamic even without sound.


6. Stopping or Canceling Vibrations

To stop all ongoing vibrations:

navigator.vibrate(0);

This immediately clears any queued vibration pattern.


7. Combining the Vibration API with Other Features

a. Push Notifications

Create immersive web notifications.

self.registration.showNotification('You have a new alert!', {
body: 'Tap to open your dashboard.',
vibrate: [200, 100, 200]
});

b. Battery Awareness

Avoid draining the battery; only vibrate when it’s not low.

navigator.getBattery().then(battery => {
if (battery.level > 0.3) navigator.vibrate(150);
});

c. Accessibility Enhancements

Use gentle vibrations to confirm for visually impaired users.


8. UX and Accessibility Guidelines

A little vibration goes a long way.
Here are a few best practices:

  • Keep it short: 50–200ms is ideal.
  • Never rely solely on vibration: always pair with a visual or audio cue.
  • Let users opt out: some users may find haptic feedback distracting or inaccessible.
  • Respect silent modes: some devices ignore vibrations when muted, that’s okay.

Good haptic design is subtle, not noisy.


9. Testing Your Implementation

The Vibration API doesn’t work in most desktop simulators.
 Test on a real Android device:

  1. Open your app over HTTPS.
  2. Trigger vibration via a user action (click/touch).
  3. Check the browser’s console for any ignored calls.

If nothing happens, confirm:

  • You’re not on iOS.
  • You’re using Chrome or Firefox.
  • The device’s vibration is enabled.

10. Complete Demo

<h2>Haptic Feedback Demo</h2>
<button id="success">Success</button>
<button id="error">Error</button>
<button id="pattern">Pattern</button>

<script>
document.getElementById('success').addEventListener('click', () => navigator.vibrate(150));
document.getElementById('error').addEventListener('click', () => navigator.vibrate([100, 50, 100, 50, 100]));
document.getElementById('pattern').addEventListener('click', () => navigator.vibrate([200, 100, 200, 100, 300]));
</script>

Try it on your phone; each button will “feel” different.


Conclusion

The Vibration API is one of the easiest ways to add real-world physical feedback to web apps.
 With a single function call, your app can communicate beyond the screen, confirming actions, signaling errors, or adding delight to interactions.

It’s a perfect example of how web apps can feel just as responsive as native ones when you use the browser’s hidden superpowers.

Pro Tip: Combine vibration with the Web Animations API or CSS transitions for synchronized, multi-sensory feedback that feels polished and modern.


Call to Action

Have you used the Vibration API in one of your projects?
Share your experience (or your favorite pattern) in the comments and bookmark this post for your next mobile web app build.

One response

  1. Adrian Marin Avatar
    Adrian Marin

Leave a Reply

Your email address will not be published. Required fields are marked *