React PWA Install Prompt für Chrome, Edge und iPhone

Ein React PWA Install Prompt muss zwei Arten von Browsern abdecken. Chrome, Edge und Samsung Internet feuern beforeinstallprompt, also kann dein eigener Button den Installationsdialog des Browsers öffnen. Auf iPhone und iPad feuert kein Browser dieses Event. Dort geht es nur über „Teilen“, dann „Zum Home-Bildschirm“, und deine App muss den Leuten zeigen, wo das ist. Die typischen Bugs: ein Listener in einer Komponente, die zu spät mountet, und ein Banner, das schon beim ersten Seitenaufruf fragt. Dieses Tutorial baut beide Wege in Next.js, damit die Leute deine PWA installieren können, und zeigt dann, wann du gar nicht fragen solltest.
Welche Browser lassen eine Seite den Installationsdialog öffnen?
Nur Chromium-Browser. Überall sonst installieren die Leute, wenn überhaupt, über ein Browsermenü, und die Seite kann nur erklären, wo es ist. Stand Oktober 2026, laut caniuse (opens in a new tab), dem Installierbarkeits-Guide von MDN (opens in a new tab) und den Release Notes von Firefox 143 (opens in a new tab):
Auf dem iPhone hilft dir kein Polyfill für beforeinstallprompt iOS, denn kein iOS-Browser hat einen Installationsdialog, den eine Seite öffnen könnte. WebKit hat die Anfrage von 2019 für BeforeInstallPromptEvent (Bug 193959 (opens in a new tab)) als WONTFIX geschlossen. Auf der Chromium-Seite nennen die Release Notes von Chrome 157 (opens in a new tab) eine Web Install API (opens in a new tab) (navigator.install(), zuerst auf dem Desktop) und ein <install>-Element, und laut Chromium Dash (opens in a new tab) erscheint Chrome 157 am 3. November 2026 als Stable. Die Standards Position (opens in a new tab) von WebKit zu dieser API lautet „oppose“, auf dem iPhone ändert sich also nichts. Bau heute auf beforeinstallprompt.
Was braucht Chrome, bevor es beforeinstallprompt feuert?
Ein Manifest, HTTPS und etwas Interaktion. Die Installationskriterien auf web.dev (opens in a new tab) verlangen eine App, die noch nicht installiert ist, über HTTPS läuft und deren Manifest Folgendes enthält: name oder short_name, ein Icon in 192px und eines in 512px, start_url und als display einen der Werte standalone, fullscreen, minimal-ui oder window-controls-overlay. Die Person muss außerdem einmal auf die Seite geklickt oder getippt und 30 Sekunden dort verbracht haben, zu irgendeinem Zeitpunkt. Deshalb kann dein PWA Install Button beim ersten Besuch versteckt bleiben, selbst mit einem perfekten Manifest. In den Chrome DevTools zeigt dir Application, dann Manifest, woran die Installierbarkeit scheitert.
Ein Service Worker ist laut MDN für die Installierbarkeit optional. Chromes Beitrag Revisiting Chrome's installability criteria (opens in a new tab) (zuletzt aktualisiert im Dezember 2023) hat die Pflicht zu einem fetch()-Handler für die Installation über das Menü gestrichen (Chrome 108 auf Mobilgeräten, 112 auf dem Desktop), aber festgehalten, dass der automatische Install Prompt weiter davon abhängt. Wenn du dich auf das Event verlässt, registrier trotzdem einen Service Worker mit Fetch-Handler; Offline-Support braucht ihn ohnehin.
Im App Router ist das Manifest eine Dateikonvention:
Wie fängst du beforeinstallprompt in React ab?
In einem Store auf Modulebene, der zu lauschen beginnt, sobald das Root-Layout mountet, nicht im State einer Komponente. Der Browser feuert das Event, sobald die Seite die Kriterien erfüllt, oft direkt nach dem Laden. Ein Event, das vor deinem Listener gefeuert hat, ist weg, also hört ein Listener auf einer Einstellungsseite, die später mountet, es nie. Ruf preventDefault() auf, damit Chromes eigene Mini-Infobar wegbleibt, speicher das Event und ruf prompt() aus einem Klick heraus auf. Das Codelab auf web.dev (opens in a new tab) ruft es im Click-Handler des Buttons auf, weil es aus einer Nutzergeste kommen muss, und setzt das gespeicherte Event zurück, weil prompt() nur einmal funktioniert. Der Event-Typ steht nicht in lib.dom.d.ts, weil er nur in Chromium existiert und nicht standardisiert ist (MDN (opens in a new tab)).
Ruf den Hook in einer Client-Komponente auf, die das Root-Layout rendert, und zeig deinen Button nur, solange canInstall true ist. useSyncExternalStore liefert auf dem Server und während der Hydration null, also verursacht der Button nie einen Hydration Mismatch. userChoice meldet, was im Dialog passiert ist, den dein Button geöffnet hat; appinstalled feuert bei jeder Installation, auch bei einer über die Adressleiste. Laut web.dev (opens in a new tab) feuert der Browser nach einer Ablehnung meist direkt nach dem Auflösen von userChoice ein frisches Event, und der Store nimmt es auf.
Wie erklärst du „Zum Home-Bildschirm hinzufügen“ auf iOS?
Erkenne iPhone und iPad, überspring die installierte App und In-App-Browser und zeig die Schritte mit den Icons, nach denen die Leute suchen werden. iPadOS meldet einen Mac-User-Agent, also prüf auch die Touch-Punkte. Der PWA-Guide in der Next.js-Doku (opens in a new tab) testet nur /iPad|iPhone|iPod/, übersieht damit aktuelle iPads, und sein Button für „Zum Home-Bildschirm“ hat keinen Handler.
iOS 26 hat zwei Dinge geändert. Laut WebKits Ankündigung der Safari 26 Beta (opens in a new tab) öffnet jede Website, die zum Home-Bildschirm hinzugefügt wird, jetzt standardmäßig als Web-App, mit einem Schalter „Als Web-App öffnen“, den man abschalten kann. Und im Standard-Tab-Layout „Kompakt“ liegt Teilen hinter dem Mehr-Button (⋯), also fehlt älteren Anleitungen für „Zum Home-Bildschirm hinzufügen“ auf iOS ein Antippen. App-Entwickler haben das im September 2025 in einem Thread der Glide-Community (opens in a new tab) gemeldet, und die Anleitung von iPhone Life zu iOS 26.4 (opens in a new tab) ergänzt vor „Zum Home-Bildschirm“ ein Antippen von „Mehr anzeigen“. Die Layouts „Unten“ und „Oben“ behalten Teilen in der Symbolleiste, also schreib Schritte, die in allen drei funktionieren.
Wie deckt der Install Prompt von Wingo UI beide Wege ab?
Er ist eine Komponente für beide Wege. Der Install Prompt hält das Event in einem seitenweiten Store, wie der Hook oben, und ergänzt, was der Hook auslässt: Plattformerkennung für Chromium, iPhone, iPad und Safari auf dem Mac, die Prüfungen auf Standalone und In-App-Browser, ein gemerktes „Nicht jetzt“ und die UI. Wo es keinen Installationsweg gibt, rendert er nichts.
$ npx wingo-ui@latest add install-promptDie Demo erzwingt platform="ios"; in deiner App erkennt der Standardwert auto die Plattform selbst. Das Banner erscheint delay Millisekunden (standardmäßig 3000), nachdem eine Installation möglich wird, nimmt nie den Fokus und sitzt dank --bottom-bar-offset und der Safe Area Insets über einer Bottom Tab Bar und dem Home-Indikator. Auf dem iPhone öffnet Installieren einen Drawer mit nummerierten Schritten und einem Pfeil zu Safaris Teilen-Button; ab 768px wird daraus ein zentrierter Dialog. Auf dem Mac bekommt Safari die Schritte „Ablage“, dann „Zum Dock hinzufügen“ direkt im Banner.
$ npx wingo-ui@latest add install-promptMounte ihn einmal, möglichst weit oben im Baum. Dieser Wrapper hält ihn außerdem von Screens fern, auf denen er eine Aufgabe unterbrechen würde, und schreibt die iPhone-Schritte für iOS 26 um:
Für eine Einstellungsseite platziert variant="card" denselben Prompt inline. Für einen Menüeintrag liefert useInstallPrompt() die Werte platform, canInstall, isStandalone und promptInstall(), dessen Promise accepted, dismissed oder unavailable liefert.
Wann solltest du nicht zur Installation auffordern?
Frag, nachdem die Leute einen Nutzen hatten, und sei überall sonst still. Die Muster zur Installationswerbung auf web.dev (opens in a new tab) halten fest, dass störende Hinweise Bedienbarkeit und Engagement schaden, dass man ein Registrierungsformular nicht unterbrechen soll und dass ein abgelehnter Hinweis ausgeblendet bleiben soll, bis sich etwas ändert, etwa eine Anmeldung oder ein Kauf. Lass den Hinweis weg:
- Bei der Ankunft. Chrome wartet schon auf einen Tipp und 30 Sekunden; das iPhone hat keine solche Hürde, also ist dein
delaydie einzige. - Mitten in einer Aufgabe. Registrierung, Checkout und Onboarding stehen oben auf der
BUSY-Liste. Bei einem mehrstufigen Ablauf wartest du, bis der letzte Schritt erledigt ist. - In der installierten App. Prüf
display-mode: standaloneundnavigator.standalone. Die Komponente behandelt auchminimal-uiundwindow-controls-overlayals installiert. - In einem In-App-Browser. Ein Link, der aus Instagram oder TikTok geöffnet wird, hat keinen Installationsweg, und der Install Prompt rendert dort nichts. Kommt viel Traffic auf diesem Weg, hat die MIT-lizenzierte Web-Komponente pwa-install (opens in a new tab) in 0.7.0 (opens in a new tab) (September 2026) eine Erkennung von In-App-Browsern mit geführten Schritten ergänzt, etwa den Link in Safari zu öffnen. Unsere Komponente kann das nicht.
- Über einem anderen Banner. Immer nur eine schwebende Nachricht. Fixierte Install-Banner reihen sich hintereinander ein, aber die Reihenfolge mit einem Cookie-Banner legst du selbst fest.
- Gleich wieder nach „Nicht jetzt“. Das × speichert einen Zeitstempel in localStorage unter
storageKeyund blendet den Prompt fürdismissDaysaus (standardmäßig 14;0heißt nur für diese Sitzung).
Wie kombinierst du den Install Prompt mit dem Onboarding?
Bitte nach dem Onboarding um die Installation, und frag auf dem iPhone in der installierten App nach Benachrichtigungen. WebKits Ankündigung zu iOS 16.4 (opens in a new tab) hat Web Push für Web-Apps auf dem Home-Bildschirm eingeführt, wobei die Berechtigungsanfrage an eine direkte Nutzerinteraktion gebunden ist. Der Onboarding Flow fragt auf einem eigenen Schritt nach Benachrichtigungen und Standort, also lass die Karte für Benachrichtigungen in einem Safari-Tab weg:
$ npx wingo-ui@latest add onboarding-flowSlides, Interessen, Beispielnutzer und Labels des Blocks zeigen standardmäßig seinen Demo-Inhalt Acme Market. Gib also slides, interests, user und labels für deine eigene App mit, bevor du live gehst. Sind die Leute fertig, erscheint das Banner nach seinem delay auf der Startseite: Sie haben die App gerade eingerichtet, und kein Formular konkurriert um den Bildschirm. Für den Rest der mobilen Ebene lies Mobile-first React-Komponenten, ergänze Pull to Refresh für die PWA oder stöber in Mobile UI in React.
Was installierst du als Nächstes?
Füg die Komponente hinzu, dann das Manifest und den Wrapper für das Root-Layout von oben. npx wingo-ui@latest add install-prompt kopiert sie mit Button, Drawer und den Hooks, die sie importiert, und installiert die npm-Pakete, die diese nutzen (motion, lucide-react, vaul und drei Radix-Primitives). Install Prompt und Onboarding Flow gehören zu Wingo UI Pro, also melde dich zuerst mit npx wingo-ui@latest login an; Button und Drawer darunter sind kostenlos. Das Tutorial zum React Onboarding Flow zeigt, wo das Installationsangebot nach den Willkommens-Slides und den Berechtigungsanfragen hinpasst, und React Native vs PWA klärt, wann eine installierte Web-App reicht.
Häufige Fragen
Funktioniert beforeinstallprompt auf iOS?
Nein. Kein Browser auf iPhone oder iPad feuert es, und WebKit hat die Anfrage von 2019, BeforeInstallPromptEvent einzubauen (Bug 193959), als WONTFIX geschlossen. Installiert wird über das Teilen-Menü, in Safari oder seit iOS 16.4 auch in anderen Browsern, die die Option ergänzt haben, etwa Chrome und Edge. Eine Seite kann also nur diese Schritte zeigen.
Warum feuert beforeinstallprompt nicht?
Chrome feuert es nur für eine App, die noch nicht installiert ist, über HTTPS ausgeliefert wird und ein Manifest mit name, Icons in 192px und 512px, start_url und einem standalone-artigen display hat, und erst, nachdem die Person einmal auf die Seite getippt und irgendwann 30 Sekunden dort verbracht hat. Oft feuert es direkt nach dem Laden, also verpasst ein Listener, der später auf einer anderen Route mountet, das Event; in den Chrome DevTools zeigt Application, dann Manifest, was fehlt.
Wie erkenne ich, ob meine PWA schon installiert ist?
In der installierten App trifft matchMedia('(display-mode: standalone)') zu, und auf iOS ist zusätzlich navigator.standalone true. In Chromium feuert das Event appinstalled im Moment der Installation auf der Seite, egal welcher Button sie gestartet hat.
Kann ich den Install Prompt nach einer Ablehnung erneut zeigen?
Jedes beforeinstallprompt-Event kann prompt() einmal aufrufen; nach einer Ablehnung wartest du, bis der Browser ein neues Event feuert, laut web.dev meist direkt nachdem userChoice aufgelöst ist. Dein eigenes Banner sollte sich ein „Nicht jetzt“ ebenfalls eine Weile merken; der Install Prompt von Wingo UI blendet sich standardmäßig 14 Tage lang aus.
Ist der Install Prompt von Wingo UI kostenlos?
Nein. Der Install Prompt und der Block Onboarding Flow sind Pro-Items, der Button und der Drawer, auf denen der Prompt aufbaut, sind kostenlos. Mit einem Pro-Konto, angemeldet über npx wingo-ui@latest login, kopiert npx wingo-ui@latest add install-prompt die Komponente samt allem, was sie importiert, in dein Projekt.
- Mobile UI
- PWA
- Install Prompt
- React
- Next.js


