# Web Vibration API: Haptik auf Android und iPhone

> Web Vibration API 2026: navigator.vibrate auf Android, der iPhone-Switch-Tick, den iOS 26.5 auf echte Taps begrenzt, und ein React-Helper, der still scheitert.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 9. Okt. 2026
- Kategorie: [Mobile UI mit React](https://wingo-ui.com/de/blog/category/mobile-ui)
- Lesezeit: 11 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/web-vibration-api-haptic-feedback
- Englische Fassung: https://wingo-ui.com/blog/web-vibration-api-haptic-feedback

## Kurz gesagt

Stand Oktober 2026 funktioniert die Web Vibration API (navigator.vibrate) nur in Chromium-Browsern auf Android, nur nachdem jemand die Seite angetippt hat, und ohne Kontrolle über die Intensität; Safari auf dem iPhone hat sie nie ausgeliefert. Die einzige Haptik, die eine Seite auf dem iPhone auslösen kann, ist der System-Tick eines nativen HTML-Switch, und seit iOS 26.5 spielt WebKit ihn nur ab, wenn der Nutzer den Switch selbst antippt, nie bei einem Klick aus JavaScript. Pack navigator.vibrate hinter einen Helper, der false zurückgibt statt zu werfen, leg ein Label für einen versteckten Switch über Buttons, die auf dem iPhone ticken sollen, und lass einen Tick nie das einzige Feedback sein.

Ein Tap soll unter dem Daumen ticken wie in einer nativen App, also greifst du zur Web Vibration API. Auf einem Android-Smartphone klappt `navigator.vibrate(10)` beim ersten Versuch. Auf dem iPhone passiert nichts, auf dem Laptop gibt der Aufruf `true` zurück und es passiert ebenfalls nichts, und der iPhone-Workaround, den du auf GitHub gefunden hast, funktioniert seit iOS 26.5 nicht mehr. Dieses Tutorial zeigt, was eine Seite im Oktober 2026 wirklich auslösen kann, baut einen Helper, der überall still bleibt, wo er nichts abspielen kann, und baut Haptik in React in einen Switch, einen Button und einen Wheel Picker ein.

## Was kann die Web Vibration API 2026?

Sie schaltet den Vibrationsmotor für die Millisekunden an und aus, die du angibst, und zwar in Chromium-Browsern auf Android, sobald jemand die Seite angetippt hat. Das ist die ganze API: eine Methode, navigator.vibrate, die eine Zahl oder ein Array aus abwechselnden Vibrations- und Pausenzeiten nimmt. Es gibt keine Intensität, keine Wellenform und keinen Weg, zu fragen, ob das Gerät überhaupt einen Motor hat. Software Mansions [Überblick über Web-Haptik vom August 2026](https://swmansion.com/blog/haptic-feedback-on-the-web-why-the-web-deliberately-refuses-to-be-as-tactile-as-native-apps) fasst den Stand in einem Satz zusammen: Praktisch beschränkt sich die Vibration API auf Browser, die auf Chromium basieren.

Hier siehst du, wo ein Tick wirklich beim Finger ankommt, Stand Oktober 2026 ([caniuse](https://caniuse.com/vibration) für den Support, unser eigener Test in Chromium auf dem Desktop für die letzte Zeile):

| Wo die Seite läuft | `navigator.vibrate` | Was der Nutzer spürt |
| --- | --- | --- |
| Chrome oder Samsung Internet auf Android | unterstützt | das übergebene Muster, sobald die Seite einen Tap gesehen hat |
| Firefox | in Version 129 entfernt, auf Android nicht unterstützt | nichts |
| Safari auf dem iPhone und Web-Apps auf dem Homescreen | nie ausgeliefert | den System-Tick eines nativen Switch, nur wenn der Nutzer ihn selbst antippt |
| Chrome auf dem Desktop | vorhanden, gibt `true` zurück | nichts, es gibt keinen Motor |

Die letzte Zeile ist die Falle. Feature Detection mit `"vibrate" in navigator` sagt in Chrome auf dem Desktop ja, verrät also nichts über die Hardware. Der Boolean, den `navigator.vibrate()` zurückgibt, sagt nur, dass der Browser das Muster angenommen hat. Ob es jemand gespürt hat, sagt er nicht.

## Wie verhält sich navigator.vibrate auf Android?

Es spielt das übergebene Muster ab und ersetzt jedes Muster, das gerade läuft. Die Grenzen dafür kannst du im [Vibration Controller](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/modules/vibration/vibration_controller.cc) von Chromium nachlesen:

```ts
navigator.vibrate(8); // ein Puls von 8ms: ein leichter Tick
navigator.vibrate([10, 60, 16]); // Puls, Pause, Puls: ein Erfolgsmuster
navigator.vibrate(0); // bricht ab, was gerade läuft ([] ebenso)
```

- **Erst muss ein Tap kommen.** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate) nennt Sticky User Activation als Voraussetzung. Bis die Seite einen Tap, einen Klick oder einen Tastendruck gesehen hat, gibt Chrome `false` zurück und loggt `Blocked call to navigator.vibrate because user hasn't tapped on the frame or any embedded frame yet`. Ist die Aktivierung einmal da, hält sie, bis die Seite navigiert. Ein Tick aus einem Scroll-Handler oder nach einem `await` funktioniert danach also.
- **Im Hintergrund bleibt es still.** Der Aufruf gibt `false` zurück, solange die Seite verborgen ist.
- **Lange Muster werden gekürzt.** Chromium begrenzt jeden Eintrag auf 10.000ms, behält die ersten 99 Einträge und verwirft eine abschließende Pause.
- **Das Smartphone kann dich überstimmen.** MDN weist darauf hin, dass manche Geräte im Lautlos- oder Nicht-stören-Modus nicht vibrieren.

Halt die Pulse kurz; der Helper unten nutzt 4 bis 22ms pro Puls. Das Brummen von 200ms, das viele Beispiele nutzen (auch das erste bei MDN), fühlt sich wie eine Benachrichtigung an. Für einen Toggle ist das die falsche Botschaft.

## Funktioniert die Web Vibration API auf iOS?

Nein. Safari hat navigator.vibrate nie implementiert, und caniuse führt bis 27.2 keine Safari-Version auf iOS damit. Wer nach Vibration API iPhone Support sucht, landet bei genau einem Workaround: Safari 17.4 hat ein natives Switch-Control eingeführt, `<input type="checkbox" switch>` ([Ankündigung von WebKit](https://webkit.org/blog/15054/an-html-switch-control/)), und das Umschalten spielt den haptischen System-Tick ab.

Bis iOS 26.5 haben Bibliotheken wie ios-haptics diesen Tick auf Abruf ausgelöst, indem sie `.click()` auf einem versteckten Label aufriefen, das mit dem Switch verbunden war. Das funktioniert nicht mehr. Laut der [README von ios-haptics vom April 2026](https://www.npmjs.com/package/ios-haptics/v/0.1.5) klappt der Trick nur noch auf iOS 17.4 bis 26.4, weil Apple ihn in iOS 26.5 gepatcht hat. Der [WebKit-Fix](https://commits.webkit.org/313638@main), am 21. Mai 2026 in den Main-Branch gemergt, schließt diese Lücke: WebKit verlangte für die Haptik schon User Activation und verlangt jetzt zusätzlich ein Trusted Event. Ein Klick, den `label.click()` weiterreicht, ist das nicht mehr.

Was weiter funktioniert, ist ein echter Tap, der auf einem Label für den Switch landet. Der Tap erzeugt einen Trusted Click, das Label reicht ihn an den Switch weiter, und weil der ursprüngliche Klick trusted war, lässt die Änderung in WebKit den Switch trotzdem ticken. Der [Quellcode von ios-haptics](https://github.com/tijnjh/ios-haptics) ist am 22. September 2026 genau darauf umgestiegen: Er legt ein transparentes Label über dein Element. Hier dieselbe Idee als Komponente für React 19:

```tsx
// components/ios-tap-tick.tsx
"use client";

// iOS spielt die Switch-Haptik nur bei einem Trusted Click, also muss der eigene Tap auf einem Label für den Switch landen.
// in einen positionierten Button setzen; es deckt den Button ab, und der Klick bubbelt trotzdem zum onClick des Buttons
export function IOSTapTick() {
  return (
    <label
      aria-hidden="true"
      data-slot="ios-tap-tick"
      className="absolute inset-0 touch-manipulation [-webkit-tap-highlight-color:transparent]"
    >
      <input
        type="checkbox"
        // react 19 reicht das unbekannte Attribut durch; der Spread hält TypeScript ruhig
        {...{ switch: "" }}
        tabIndex={-1}
        // unter dem Finger liegt das Label, nicht der Switch, also scrollt ein Swipe, der hier beginnt, weiter die Seite
        className="invisible absolute m-0 size-px"
        // das Label reicht den Klick an den Switch weiter: diesen zweiten Klick stoppen, bevor er den Button erreicht
        onClick={(event) => event.stopPropagation()}
      />
    </label>
  );
}
```

Setz es in Buttons ein, nicht in Links: In unserem Test in Chromium hat ein Label in einem `<a>` zwar das `onClick` des Links ausgeführt, aber die Standardaktion übernommen, und der Link hat nie navigiert. Gib dem Input keinen `name`, damit er nie in einem Formular-Submit landet. Außerhalb von iOS schaltet ein Tap darauf nur eine versteckte Checkbox um, die niemand sieht. Es kann also auf jeder Plattform rendern und verursacht nie einen Hydration Mismatch.

Auf dem iPhone bekommst du einen festen Tick pro Tap, ausgelöst vom Tap selbst: keine Muster, nichts nach einem `await`, nichts während eines Drags und nichts für ein Rad, das an Zeilen vorbeidreht, weil ein Scroll nie einen Klick erzeugt.

## Wie rufst du navigator.vibrate sicher auf, wenn es nicht unterstützt wird?

Prüf die Methode selbst, prüf die Aktivierung, fang alles ab und gib einen Boolean zurück. Hier der ganze Helper ohne Abhängigkeiten:

```ts
// lib/vibrate.ts
export type HapticKind = "selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error";

const PATTERNS: Record<HapticKind, number | number[]> = {
  selection: 4,
  light: 8,
  medium: 14,
  heavy: 22,
  success: [10, 60, 16],
  warning: [16, 70, 16],
  error: [22, 50, 22, 50, 22],
};

let enabled = true;

export function setHapticsEnabled(value: boolean) {
  enabled = value;
}

export function vibrate(kind: HapticKind = "light"): boolean {
  if (!enabled) return false;
  // node 21+ hat auch ein globales navigator, also auf die Methode prüfen, nicht auf navigator
  if (typeof navigator === "undefined" || typeof navigator.vibrate !== "function") return false;
  // chrome blockiert den Aufruf (und loggt eine Warnung), bis die Seite einen Tap gesehen hat
  if (navigator.userActivation && !navigator.userActivation.hasBeenActive) return false;
  try {
    return navigator.vibrate(PATTERNS[kind]);
  } catch {
    return false; // Feedback ist nie eine Exception wert
  }
}
```

Die Prüfung für Node ist wichtig. Node 21 und neuer definieren ein globales `navigator` ohne `vibrate`. Ein Helper, der nur `typeof navigator` prüft, kommt auf dem Server also an seinem Guard vorbei und ruft eine Methode auf, die es nicht gibt.

Der [Haptics-Helper](https://wingo-ui.com/components/haptics) von Wingo UI ist dieselbe Idee plus ein Fallback fürs iPhone und eine Option `force`, die einen Tick auch dann abspielt, wenn Haptik aus ist. `haptic(kind)` gibt zurück, ob eine Haptik gesendet wurde, `configureHaptics({ enabled, iosFallback })` setzt die Optionen für die ganze App, und `supportsHaptics()` sagt dir, ob der Browser überhaupt einen Weg für Haptik anbietet (ruf es in einem Effect auf: Auf dem Server ist es `false`, und in Chrome auf dem Desktop aus dem oben genannten Grund `true`).

> Live-Demo (Haptics): Tipp auf einem Android-Smartphone jede Kachel an, um die sieben Arten zu spüren; die Balken zeichnen jedes Vibrationsmuster, und die Zeile unter der Karte zeigt, was haptic() zurückgegeben hat. Probier sie unter [Haptics](https://wingo-ui.com/components/haptics) aus und installier sie mit `npx wingo-ui@latest add haptics`.

Ein Vorbehalt zu unserem eigenen Code: Die Option `iosFallback` des Helpers, standardmäßig an, klickt weiterhin per Skript auf ein verstecktes Label. Das tickt auf iPhones bis iOS 26.4, wird ab 26.5 ignoriert, und der Aufruf gibt dort trotzdem `true` zurück, weil WebKit nichts zurückmeldet. Wenn du das Tap-Overlay von oben einbaust, ruf einmal `configureHaptics({ iosFallback: false })` auf, damit iPhones mit älteren Versionen nicht doppelt ticken.

Die Snippets unten importieren den Helper von Wingo UI. Mit der abhängigkeitsfreien Datei von oben importierst du stattdessen `vibrate` aus `@/lib/vibrate` und nutzt `setHapticsEnabled` statt `configureHaptics`; eine Option `force` hat sie nicht.

## Welche Haptik passt zu welcher Interaktion?

Ein Tick pro Ereignis, abgestimmt auf dessen Gewicht. Diese Muster sendet der Helper auf Android:

| Art | Muster (ms) | Wofür | Komponente von Wingo UI, die es abspielt |
| --- | --- | --- | --- |
| `selection` | 4 | eine Zeile eines Rads oder ein Slider-Schritt, der die Mitte passiert | Picker Wheel |
| `light` | 8 | ein Tap, ein Toggle | Haptic Button beim Drücken |
| `medium` | 14 | ein Long Press, ein Einrasten, eine überschrittene Schwelle | Haptic Button bei Long Press, Pull To Refresh beim Scharfschalten, Slide To Confirm scharf geschaltet |
| `heavy` | 22 | ein abgeschlossener voller Swipe, ein Drop | keine; ruf es aus deinem eigenen Drop-Handler auf |
| `success` | 10, 60, 16 | Zahlung gesendet, Eintrag gespeichert | Haptic Button bei bestätigtem Halten, Slide To Confirm fertig |
| `warning` | 16, 70, 16 | ein erreichtes Limit, zu früh losgelassenes Halten | Haptic Button bei Tap im Hold-Modus |
| `error` | 22, 50, 22, 50, 22 | eine falsche PIN, ein fehlgeschlagenes Speichern | Haptic Button bei abgelehntem Promise |

Drei Regeln verhindern, dass daraus Rauschen wird. Ruf es aus dem Handler einer echten Geste auf, nie aus einem Effect oder beim Rendern. Tick nie pro Animationsframe; tick, wenn sich ein Zustand ändert, etwa wenn eine Zeile die Mitte erreicht. Und leg Information nie nur in den Tick: Leute am Desktop, Leute mit iPhone an einem Rad und alle mit lautlos gestelltem Smartphone spüren ihn nicht, also muss der Bildschirm dasselbe zeigen.

## Wie baust du React Haptic Feedback in einen Switch, einen Button und ein Rad ein?

Ruf `haptic()` in dem Handler auf, in dem sich der Zustand ändert, einmal pro Änderung.

### Ein Switch

Der kostenlose [Switch](https://wingo-ui.com/components/switch) ruft `onCheckedChange` bei jedem Klick, jeder Taste und jedem Drag auf, und gibst du ein Promise zurück, zeigt er einen Spinner und springt bei einem fehlgeschlagenen Speichern mit `errorText` zurück. Tick bei der Änderung und noch einmal bei einem Fehler:

```tsx
"use client";

import { Switch } from "@/components/ui/switch";
import { haptic } from "@/lib/haptics";

export function NewMessagesSetting({ save }: { save: (on: boolean) => Promise<void> }) {
  return (
    <Switch
      label="Neue Nachrichten"
      description="Wenn dir jemand zu einem Inserat schreibt"
      labelPosition="start"
      defaultChecked
      onCheckedChange={async (on) => {
        haptic("light");
        try {
          await save(on);
        } catch (error) {
          haptic("error");
          throw error; // der Switch springt zurück und zeigt errorText
        }
      }}
    />
  );
}
```

Ab iOS 26.5 bleibt dieser Switch still: Er ist ein Radix-Button mit `role="switch"`, nicht der native Input, also kommt mit dem Tap kein System-Tick, und `haptic()` erreicht den Switch-Tick aus dem Skript nicht. Ist dir ein iPhone-Tick an einem Einstellungs-Toggle wichtiger als das eigene Design, tickt ein schlichtes `<input type="checkbox" switch>` von selbst und rendert in Browsern, die das Attribut nicht kennen, als Checkbox.

### Ein Button

Der [Haptic Button](https://wingo-ui.com/components/haptic-button) spielt die in `hapticKind` gesetzte Art (Standard `light`) nur bei Touch- und Stift-Eingaben ab, ein Mausklick fordert also nie eine Vibration an. Mit `mode="hold"` spielt er light, wenn das Halten beginnt, success, sobald `onConfirm` fertig ist, warning bei einem zu kurzen Tap und error, wenn `onConfirm` mit einem Fehler endet; mit gesetztem `onLongPress` spielt ein Long Press medium.

```tsx
"use client";

import { Send } from "lucide-react";
import { HapticButton } from "@/components/ui/haptic-button";

export function SendRent({ onSend }: { onSend: () => Promise<void> }) {
  return (
    <HapticButton mode="hold" fullWidth leftIcon={<Send />} labels={{ holdHint: "Zum Senden halten" }} onConfirm={onSend}>
      Halten, um $1,850 zu senden
    </HapticButton>
  );
}
```

> Live-Demo (Haptic Button): Halte den Button „Hold to send“ auf einem Android-Smartphone mit dem Finger: Ein leichter Tick startet die Füllung, ein Erfolgsmuster kommt mit dem Haken, und ein kurzer Tap lässt den Button mit einem Warn-Tick wackeln. Probier sie unter [Haptic Button](https://wingo-ui.com/components/haptic-button) aus und installier sie mit `npx wingo-ui@latest add haptic-button`.

Für einen normalen [Button](https://wingo-ui.com/components/button), der auf beiden Plattformen ticken soll, kombinierst du den Aufruf und das Overlay. Der Button ist schon `position: relative`, das Overlay deckt ihn also ab:

```tsx
"use client";

import { Button } from "@/components/ui/button";
import { IOSTapTick } from "@/components/ios-tap-tick";
import { haptic } from "@/lib/haptics";

export function SaveButton({ onSave }: { onSave: () => Promise<void> }) {
  return (
    <Button
      onClick={async () => {
        haptic("light"); // android; auf dem iPhone tickt das Overlay
        try {
          await onSave();
          haptic("success"); // nur android: das iPhone hat nach einem await keinen Tick
        } catch {
          haptic("error");
        }
      }}
    >
      Speichern
      <IOSTapTick />
    </Button>
  );
}
```

### Ein Rad

Das [Picker Wheel](https://wingo-ui.com/components/picker-wheel) spielt jedes Mal einen `selection`-Tick, wenn eine neue Zeile die Mitte erreicht, solange ein Finger, ein Maus-Drag oder ein Scrollrad es bewegt, und nie bei Tasten, Klicks oder Wertänderungen von außen. `haptics={false}` schaltet das ab.

```tsx
"use client";

import { PickerWheel, pickerRange } from "@/components/ui/picker-wheel";

const hours = pickerRange(8, 19, { pad: 2 });
const minutes = pickerRange(0, 55, { step: 5, pad: 2 });

export function AppointmentTime() {
  return (
    <PickerWheel
      aria-label="Uhrzeit des Termins"
      loop
      defaultValue={["10", "30"]}
      columns={[
        { id: "hour", label: "h", options: hours },
        { id: "minute", label: "min", options: minutes },
      ]}
    />
  );
}
```

> Live-Demo (Picker Wheel): Wisch auf einem Android-Smartphone schnell über eine Spalte: Jede Zeile, die die Mitte erreicht, tickt einmal, und der Wert ändert sich, wenn das Rad zur Ruhe kommt. Probier sie unter [Picker Wheel](https://wingo-ui.com/components/picker-wheel) aus und installier sie mit `npx wingo-ui@latest add picker-wheel`.

Hier zeigt sich die Lücke zwischen den Plattformen am deutlichsten. Auf Android tickt jede Zeile, die die Mitte passiert. Auf dem iPhone bleibt das Rad ab iOS 26.5 still, weil das Drehen ein Scrollen ist und nie den Trusted Click erzeugt, den der Switch braucht. Dort übernehmen das Band, die Neigung und das Einrasten das Feedback.

## Wie lässt du Nutzer die Haptik abschalten?

Gib ihnen eine Einstellung und reich sie einmal an den Helper weiter. Haptisches Feedback braucht in jeder Web-App so einen Schalter: Manche Leute finden Vibration störend, und der Browser gibt einer Seite keinen Weg, die Haptik-Einstellung des Smartphones zu lesen.

```tsx
"use client";

import { useEffect, useState } from "react";
import { Switch } from "@/components/ui/switch";
import { configureHaptics, haptic } from "@/lib/haptics";

export function VibrationSetting() {
  const [on, setOn] = useState(true);

  useEffect(() => {
    configureHaptics({ enabled: on });
  }, [on]);

  return (
    <Switch
      label="Vibration"
      description="Ein kurzer Tick beim Tippen, Halten oder Auswählen"
      labelPosition="start"
      checked={on}
      onCheckedChange={(next) => {
        setOn(next);
        // der Effect ist noch nicht gelaufen, also den Bestätigungs-Tick erzwingen
        if (next) haptic("light", { force: true });
      }}
    />
  );
}
```

Speicher den Wert zusammen mit den übrigen Einstellungen des Nutzers. Jede Komponente, die über den Helper tickt, folgt ihm ohne Prop: der Haptic Button, das Picker Wheel und das Pull To Refresh aus unserem [Guide zu Pull to Refresh](https://wingo-ui.com/de/blog/react-pull-to-refresh), um nur einige zu nennen.

## Was kommt nach navigator.vibrate?

Eine semantische API mit benannten Effekten, falls die Browser den Entwurf übernehmen, der gerade entsteht. Die [Web Haptics API](https://github.com/WICG/web-haptics) begann im März 2026 als [Vorschlag an die CSS Working Group](https://github.com/w3c/csswg-drafts/issues/13728) und ist seit April bei der WICG in Arbeit. Ihr Entwurf hat einen Aufruf `navigator.playHaptics(effect, intensity)` und eine verschachtelte CSS-Regel `@haptic`, mit sechs benannten Effekten (hint, edge, tick, align, success, error) und einer Intensität von 0 bis 1, die der Browser auf die Haptik der Plattform abbildet. Der Aufruf gibt `undefined` zurück, eine Seite erfährt also nichts über das Gerät. Stand Oktober 2026 führt [Chrome Platform Status](https://chromestatus.com/feature/5167864517623808) Web haptics als Proposed, und kein stabiler Browser liefert es aus.

Die Form kennst du schon: benannte Arten statt Mustern in Millisekunden. Wenn deine App schon jeden Tick durch einen einzigen Aufruf `haptic(kind)` schickt, änderst du beim Umstieg auf eine neue API später genau eine Datei.

## Wo fängst du an?

Bau zuerst einen Helper ein und lass dann die drei Stellen ticken, die Leute am häufigsten berühren: Toggles, den Haupt-Button und jedes Rad oder jeden Slider. Die Datei `lib/vibrate.ts` ohne Abhängigkeiten von oben deckt Android ab. `npx wingo-ui@latest add haptics` kopiert stattdessen `lib/haptics.ts` von Wingo UI; der Helper gehört zu [Wingo UI Pro](https://wingo-ui.com/de/pricing), wie der Haptic Button und das Picker Wheel, der Switch ist kostenlos. Für den Rest der Smartphone-Checkliste (Bottom Sheets, [Touch Targets von 44px](https://wingo-ui.com/de/blog/minimum-touch-target-size-react-tailwind), [Safe Area Insets](https://wingo-ui.com/de/blog/tailwind-safe-area-insets)) lies [Mobile-first React-Komponenten](https://wingo-ui.com/de/blog/mobile-first-react-components) oder stöbere in der Kategorie [Mobile UI in React](https://wingo-ui.com/de/blog/category/mobile-ui).

## Komponenten in diesem Artikel

- [Haptics](https://wingo-ui.com/components/haptics) (Pro): Haptic feedback for the web in one call: short vibration ticks on Android and the system tick on iPhone, silent everywhere else. Installation: `npx wingo-ui@latest add haptics`
- [Haptic Button](https://wingo-ui.com/components/haptic-button) (Pro): A React haptic button that feels native: spring press, touch ripple, a haptic tick, a long-press action and a hold-to-confirm mode. Installation: `npx wingo-ui@latest add haptic-button`
- [Switch](https://wingo-ui.com/components/switch) (Free): A React toggle switch for settings that apply at once: a spring thumb that stretches and drags, thumb icons, and async saves that roll back. Installation: `npx wingo-ui@latest add switch`
- [Picker Wheel](https://wingo-ui.com/components/picker-wheel) (Pro): A React iOS-style picker wheel whose columns spin with momentum and snap on a 3D cylinder. Installation: `npx wingo-ui@latest add picker-wheel`

## Häufige Fragen

### Funktioniert navigator.vibrate auf dem iPhone?

Nein. Safari hat die Vibration API nie implementiert, und caniuse führt Stand Oktober 2026 keine Safari-Version auf iOS mit Unterstützung. Die einzige Haptik, die eine Webseite auf dem iPhone erzeugen kann, ist der System-Tick eines nativen Switch-Inputs, und seit iOS 26.5 spielt ihn nur ein echter Tap des Nutzers ab.

### Warum gibt navigator.vibrate auf meinem Laptop true zurück?

Weil true nur heißt, dass der Browser das Muster angenommen hat. Chrome auf dem Desktop bietet navigator.vibrate an und gibt, sobald die Seite einen Klick gesehen hat, für ein gültiges Muster true zurück, obwohl kein Motor da ist. Nutz den Rückgabewert, um Ablehnungen zu erkennen, aber nie als Hinweis auf Hardware.

### Warum tut navigator.vibrate auf meinem Android-Smartphone nichts?

Die üblichen Gründe sind eine Seite, die noch nicht angetippt wurde (Chrome blockiert den Aufruf und loggt eine Warnung, bis die Seite Sticky User Activation hat), ein Tab im Hintergrund, Lautlos- oder Nicht-stören-Modus oder Firefox, das die API in Version 129 entfernt hat.

### Kann eine Webseite die Stärke der Vibration steuern?

Nicht mit der Vibration API, die den Motor nur für die angegebenen Dauern an- und ausschaltet. Der Vorschlag für eine Web Haptics API, seit April 2026 in der WICG inkubiert, bringt benannte Effekte mit einer Intensität von 0 bis 1, aber Stand Oktober 2026 liefert ihn kein stabiler Browser aus.

### Ist der Haptics-Helper von Wingo UI kostenlos?

Nein. Der Haptics-Helper, der Haptic Button und das Picker Wheel gehören zu Pro; der Switch ist kostenlos. Mit einem Pro-Account, angemeldet über npx wingo-ui@latest login, kopiert npx wingo-ui@latest add haptics die Datei lib/haptics.ts in dein Projekt.

---

Quelle: https://wingo-ui.com/de/blog/web-vibration-api-haptic-feedback
