How to Make a Button That Vibrates Your Phone with a PWA

In my last post I explained what a PWA is: a website that acts like an app. Now let's build one. The easiest first project is a button that makes your phone vibrate.
It takes 4 small files and about 15 minutes.
How vibration works
Browsers include a built-in function for this:
navigator.vibrate([200, 100, 200]);
The numbers are milliseconds: vibrate 200, pause 100, vibrate 200. To stop it, use navigator.vibrate(0).
The files
Put these 4 files in one folder, plus two PNG icons named icon-192.png and icon-512.png
1. index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="manifest.json">
<title>Vibrate PWA</title>
</head>
<body>
<h1>Vibrate my phone</h1>
<button id="btn">Vibrate</button>
<p id="msg"></p>
<script src="app.js"></script>
</body>
</html>
2. app.js
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("sw.js");
}
const btn = document.getElementById("btn");
const msg = document.getElementById("msg");
btn.onclick = () => {
if ("vibrate" in navigator) {
navigator.vibrate([200, 100, 200]);
msg.textContent = "Bzzz!";
} else {
msg.textContent = "Vibration is not supported here.";
}
};
3. manifest.json
{
"name": "Vibrate PWA",
"short_name": "Vibrate",
"start_url": "./",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2563EB",
"icons": [
{ "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
4. sw.js
const CACHE = "v1";
const FILES = ["./", "index.html", "app.js"];
self.addEventListener("install", (e) => {
e.waitUntil(
caches.open(CACHE).then((c) => c.addAll(FILES))
);
});
self.addEventListener("fetch", (e) => {
e.respondWith(
caches.match(e.request)
.then((r) => r || fetch(e.request))
);
});
What you need to know
HTTPS is required. Upload the folder to any host with HTTPS, and Chrome will offer Install app.
It needs a tap. The phone only vibrates after the user touches the button, not automatically.
Android only. It works in Chrome on Android. Safari on iPhone doesn't support it.