Um eine Web-App im App Store und bei Google Play zu veröffentlichen, kapselst du deine gebaute Web-App in ein natives Projekt mit Capacitor, fügst einige native Features hinzu, erstellst Apple- und Google-Entwicklerkonten, signierst und baust die iOS- und Android-Binaries, testest sie mit echten Nutzern, bereitest die Store-Einträge vor und reichst sie zur Prüfung ein. Dein bestehendes HTML, CSS und JavaScript läuft weiterhin in einer nativen WebView, sodass du die App nicht neu schreiben musst.
Nachfolgend findest du die 11 Schritte in der Reihenfolge, die Wartezeiten vermeidet, inklusive Befehlen für Capacitor 8 und den Store-Regeln, die im Oktober 2026 gelten.
Voraussetzungen
- Eine Web-App, die zu statischen Dateien gebaut wird (React, Vue, Angular, Svelte, Next.js static export, Nuxt generate, reines HTML oder eine App, die mit einem AI-Builder wie Lovable oder Bolt erstellt wurde).
- Node.js 22 oder neuer (Capacitor 8-Anforderung) und Bun oder ein anderer Package Manager.
- Android Studio für Android-Builds.
- Xcode 26 auf macOS für iOS-Builds oder ein Cloud-Build-Dienst, falls du keinen Mac hast.
- 99 USD pro Jahr für Apple und 25 USD einmalig für Google.
Realistischer Zeitplan
| Phase | Typischer Zeitaufwand | Parallel möglich? |
|---|---|---|
| Registrierung des Entwicklerkontos | Stunden (Einzel) bis 2 Wochen (Organisation mit neuem D-U-N-S) | Ja, ab Tag 1 starten |
| Capacitor-Setup und erster Lauf auf dem Gerät | 1 Tag | |
| Mobile Feinschliff und native Features | 3 Tage bis 3 Wochen | |
| Signierung und erste Builds | 1 Tag | |
| Google Play geschlossener Test (neue persönliche Konten) | Mindestens 14 Tage, dann Produktionszugangs-Review | Ja, mit iOS TestFlight |
| Store-Eintrag | 1 bis 2 Tage | Ja |
| App-Review | Apple meist 1–2 Tage, Google von wenigen Stunden bis zu mehreren Tagen |
Schritt 1: Heute Developer-Account beantragen
Die Account-Verifizierung lässt sich nicht beschleunigen – erledige sie also vor dem Coding.
- Apple Developer Program: 99 USD pro Jahr. Einzelpersonen benötigen einen Apple Account mit Zwei-Faktor-Authentifizierung und ihrem rechtlichen Namen. Organisationen benötigen zudem eine D-U-N-S-Nummer, eine Firmenwebsite und eine geschäftliche E-Mail-Adresse auf dieser Domain.
- die Google Play Console: Einmalig 25 USD. Organisationen benötigen eine D-U-N-S-Nummer. Rechne mit einer Identitätsprüfung.
Wenn du dich bei Google Play als Einzelperson anmeldest, unterliegt dein Account der Regel für geschlossene Tests (Schritt 9). Komplette Anleitung: so erstellst du Apple- und Google-Play-Developer-Accounts.
Schritt 2: Web-App für das Smartphone vorbereiten
Capacitor führt deine App in einer WebView aus. Was in einem Browser-Tab funktioniert, fühlt sich in einer App oft falsch an:
- Statisches Build-Output. Capacitor lädt Dateien aus dem App-Bundle. Server-Side Rendering läuft nicht auf dem Telefon. Verwende das statische Output deines Frameworks (
next buildmitoutput: 'export',nuxt generate, Vitebuild). API-Aufrufe gehen wie bisher über HTTPS an dein Backend. - Client-seitiges Routing, das auch von einem file://-Origin funktioniert. Nutze History-Routing (Capacitor liefert die App von
https://localhostauf Android undcapacitor://localhostauf iOS, damit es funktioniert) und stelle sicher, dass Deep-URLs aufindex.html. - CORS. Füge die Capacitor-Origins zu den erlaubten Origins deines API hinzu:
capacitor://localhost(iOS) undhttps://localhost(Android). - Touch statt Hover. Entferne Menüs, die nur per Hover funktionieren. Halte Tap-Ziele mindestens 44 x 44 Punkte groß.
- Safe Areas. Füge
viewport-fit=coverzum Viewport-Meta-Tag hinzu und versehe Header und Bottom Bars mitenv(safe-area-inset-top)undenv(safe-area-inset-bottom). - Offline und langsame Netzwerke. Zeige einen richtigen State statt eines leeren Screens. Reviewer testen mit instabilem WLAN.
- Keine „App herunterladen“-Banner und keine Links, die Nutzer für Kernaufgaben auf deine Website schicken.
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
Schritt 3: Capacitor hinzufügen
Aus dem Wurzelverzeichnis Ihres Web-Projekts:
bun add @capacitor/core
bun add -d @capacitor/cli
bunx cap init "My App" com.example.myapp --web-dir dist
bun add @capacitor/ios @capacitor/android
bun run build
bunx cap add ios
bunx cap add android
Verwenden Sie den tatsächlichen Ausgabeordner für --web-dir: dist für Vite, out für Next.js Static Export, .output/public für Nuxt generate, build für Create React App, dist/<project>/browser für Angular.
Die Bundle-ID (com.example.myapp) ist dauerhaft, sobald die App in den Stores ist. Verwende eine umgekehrte Domain, die du kontrollierst.
Dein capacitor.config.ts sieht jetzt so aus:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'My App',
webDir: 'dist',
};
export default config;
Capacitor 8 erstellt das iOS-Projekt standardmäßig mit dem Swift Package Manager, du brauchst also kein CocoaPods. Jedes Mal, wenn du die Web-code änderst:
bun run build
bunx cap sync
Führe es aus:
bunx cap run ios
bunx cap run android
Committe die ios/ und android/ Ordner. Das sind die code, die du bearbeiten wirst (Berechtigungen, Icons, Signing). Mehr Hintergrund findest du unter wie einfach es ist, mit Capacitor aus einer Web-App eine mobile App zu machenund falls du mit einem KI-Tool gebaut hast, bietet unser Lovable-zu-Mobile-Guide.
Schritt 4: Native Features hinzufügen, die eine App rechtfertigen
Apples Guideline 4.2 (Minimum Functionality) lehnt Apps ab, die nur eine Website in einer Shell sind. Du brauchst keine Dutzende native Features, aber die App muss sich wie eine echte App verhalten. Gängige, nützliche Ergänzungen:
| Funktion | Plugin |
|---|---|
| Push-Benachrichtigungen | @capacitor/push-notifications |
| Native Anmeldung mit Google, Apple und Facebook | @capgo/capacitor-social-login |
| Face ID / Fingerabdruck-Entsperrung | @capgo/capacitor-native-biometric |
| Kamera und Fotos | @capacitor/camera |
| In-App-Käufe und Abonnements | @capgo/capacitor-native-purchases |
| Natives Share Sheet | @capacitor/share |
| Haptik | @capacitor/haptics |
| Statusleiste und Splash Screen | @capacitor/status-bar, @capacitor/splash-screen |
| Prompt zur App-Bewertung | @capgo/capacitor-in-app-review |
| Live Updates | @capgo/capacitor-updater |
Beispiel: Zeige das native Share Sheet statt eines „Link kopieren“-Buttons.
import { Share } from '@capacitor/share';
import { Capacitor } from '@capacitor/core';
export async function shareLink(url: string, title: string) {
if (Capacitor.isNativePlatform()) {
await Share.share({ title, url });
} else {
await navigator.clipboard.writeText(url);
}
}
Wenn du digitale Inhalte oder Abos verkaufst, plane die Zahlungen jetzt. Apple und Google verlangen für digitale Güter meist ihre eigenen In-App-Kauf-Systeme. Im US App Store dürfen Apps nach dem Gerichtsurteil von 2025 auch auf externe Web-Checkouts verlinken; andere Regionen haben eigene Regeln. Physische Güter und Dienstleistungen (Lieferungen, Fahrten) können Stripe oder jeden anderen Zahlungsanbieter nutzen. Siehe In-App-Käufe mit Capacitor.
Der komplette Katalog der Capgo-Plugins ist auf der Plugins-Seite.
Schritt 5: Icons, Splashscreen und Permission-Strings
Erstelle alle Icon- und Splash-Größen aus zwei Quellbildern:
bun add -d @capacitor/assets
# assets/icon.png 1024x1024, assets/splash.png 2732x2732
bunx capacitor-assets generate
Auf iOS benötigt jede verwendete Berechtigung eine Usage Description in ios/App/App/Info.plist, sonst stürzt die App beim Abfragen ab und Apple lehnt sie ab:
<key>NSCameraUsageDescription</key>
<string>Take a photo of your receipt to attach it to an expense.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Choose receipt photos from your library.</string>
Formuliere konkrete Gründe. „Diese App benötigt die Kamera“ wird abgelehnt.
Auf Android fügen Plugins die meisten Berechtigungen selbst dem Manifest hinzu. Entferne Berechtigungen, die du nicht nutzt; Google verlangt eine Begründung für sensible Berechtigungen.
Füge außerdem ein Privacy-Manifest (PrivacyInfo.xcprivacy) hinzu, wenn dein code required-reason-APIs verwendet. Siehe die Privacy-Manifest-Guide für iOS-Apps.
Schritt 6: Signing einrichten
iOS. Du benötigst ein Apple Distribution Certificate (inklusive Private Key, meist exportiert als .p12) und ein App Store Connect Provisioning Profile für deine Bundle ID. Xcode kann diese automatisch erstellen, oder du machst es selbst, sogar ohne Mac. Lies iOS-Zertifikate und Provisioning Profiles erklärt; der iOS-Zertifikatsgenerator übernimmt den CSR-Schritt im Browser.
Android. Erstelle einen Upload-Keystore und halte ein Backup davon. Google Play nutzt Play App Signing, d. h. Google hält den finalen App-Signing-Key und du signierst Uploads mit deinem eigenen.
keytool -genkeypair -v -keystore upload-keystore.jks -alias upload \
-keyalg RSA -keysize 2048 -validity 10000
Oder nutze den Android Keystore Generator.
Schritt 7: Release-Binaries builden
Lokal
iOS (auf einem Mac mit Xcode 26, seit April 2026 für App-Store-Uploads erforderlich):
bunx cap open ios- Wähle die App hinzu Target wählen, Version und Build-Nummer festlegen und unter Signing & Capabilities das Team auswählen.
- Wähle Jedes iOS-Gerät (arm64), dann Produkte > Archiv.
- Im Organizer, App verteilen > App Store Connect > Upload.
Android:
bun run build
bunx cap sync android
cd android
./gradlew bundleRelease
Die AAB liegt in android/app/build/outputs/bundle/release/. Konfigurieren signingConfigs in einem android/app/build.gradle mit deinem Keystore, die Passwörter kommen aus Umgebungsvariablen.
Make sure targetSdkVersion 36 ist. Seit dem 31. August 2026 verlangt Google Play, dass neue Apps und Updates Android 16 (API 36) als Ziel haben, was der Capacitor 8-Standard ist.
In der Cloud
Falls du keinen Mac hast oder reproduzierbare Builds aus der CI möchtest, Capgo Build baut beide Plattformen auf gehosteten Maschinen und lädt direkt zu TestFlight und Google Play hoch:
bunx @capgo/cli@latest build credentials save --appId com.example.myapp --platform ios
bunx @capgo/cli@latest build credentials save --appId com.example.myapp --platform android
bunx @capgo/cli@latest build request com.example.myapp --platform ios --path .
bunx @capgo/cli@latest build request com.example.myapp --platform android --path .
Zugangsdaten werden nur für den Build verwendet und nicht auf Capgo-Servern gespeichert. Siehe die Capgo Build-Dokumentation.
Schritt 8: An Tester verteilen
Das Build auf echten Handys testen, bevor Apple oder Google es sehen.
- iOS: Upload zu TestFlight. Interne Tester (bis zu 100 Teammitglieder) erhalten es direkt nach der Verarbeitung; externe Tester (bis zu 10.000) nach einer kurzen Beta App Review.
- Android: Internen Test-Release in der Play Console erstellen und den Opt-in-Link teilen.
Registrierung und Login, Zahlungen im Sandbox-Modus, Push-Benachrichtigungen, Offline-Verhalten, Tastatur, die Eingabefelder überdeckt, und Back-Button-Verhalten auf Android testen. Details zu jeder Option: wie du iOS- und Android-Apps an Tester verteilst.
Schritt 9: Google Play Closed Test (neue persönliche Accounts)
Wenn dein Play-Konto ein persönliches Konto ist, das nach dem 13. November 2023 erstellt wurde, kannst du erst in Production veröffentlichen, nachdem du einen Geschlossener Test mit mindestens 12 Testern, die 14 aufeinanderfolgende Tage opt-in sind. Danach beantragst du im Play Console Dashboard Zugriff auf Production, den Google meist innerhalb einer Woche prüft.
Starte damit, sobald du einen nutzbaren Android-Build hast. Nutze eine Google Group als Testerliste, damit Leute selbst beitreten können. Veröffentliche während der 14 Tage Updates und sammle Feedback, da Google fragt, was du gelernt hast. Organisationskonten sind ausgenommen.
Schritt 10: Store-Listings vorbereiten und einreichen
Für beide Stores brauchst du: App-Name, Beschreibungen, Screenshots in den zulässigen Größen, Icon, URL zur Datenschutzerklärung, Datenschutzangaben (Apple App Privacy und Google Data safety), Altersfreigabe-Fragebogen, Support-Kontakt und einen Demo-Account, falls die App einen Login hat. Google braucht außerdem eine 1024 x 500 Feature-Grafik. Specs und Limits: So bereitest du dein Listing für App Store und Google Play vor.
Einreichen unter iOS: Erstelle in App Store Connect die Version, wähle den TestFlight-Build aus, fülle die App-Review-Informationen (Demo-Account, Notizen) aus und klicke auf Zur Überprüfung hinzufügen, dann Einreichen.
Einreichen auf Android: erstelle einen Produktions-Release mit der AAB (oder fördere den getesteten aus einem Test-Track), fülle alle App-Inhalte Erklärungen aus, setze die Länder und sende zur Prüfung.
Die häufigsten Ablehnungsgründe für Web-Apps:
- 4.2 Mindestfunktionalität: Die App ist nur Ihre Website. Fügen Sie nativen Mehrwert hinzu und entfernen Sie browserähnliche UI-Elemente.
- Login erforderlich, aber kein Demo-Konto, oder das Konto funktioniert nicht.
- Keine datenschutzfreundliche Login-Option , wenn Sie Google- oder Facebook-Login auf iOS anbieten. Richtlinie 4.8 verlangt eine gleichwertige Option zur Einschränkung der Datenerfassung; Sign in with Apple ist die übliche Wahl.
- Keine Kontolöschung innerhalb der App, wenn Benutzer Konten erstellen können.
- Digitale Käufe über Stripe , wo In-App-Käufe erforderlich sind.
- Defektes iPad-Layout da das Projekt iPad standardmäßig unterstützt.
- Fehlende oder unklare Berechtigungsstrings.
Unser Guide für die erste App-Review und Guide zur iOS-App-Einreichung im Detail durchgehen.
Schritt 11: Updates ohne Review-Wartezeit ausrollen
Nach dem Launch liegen die meisten Änderungen weiterhin im Web code. Statt für jede Korrektur einen neuen Store-Build zu erstellen, füge Live Updates hinzu. Der Capgo-Updater lädt neue Web-Bundles von Capgo herunter und wendet sie beim nächsten Start an, mit automatischem Rollback, falls das neue Bundle nicht startet.
bun add @capgo/capacitor-updater
bunx cap sync
bunx @capgo/cli@latest init
Rufe notifyAppReady() wenn deine App gestartet ist, damit der Updater weiß, dass das Bundle gesund ist:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
CapacitorUpdater.notifyAppReady();
Dann ist jede Release des Web code ein einzelner Befehl:
bun run build
bunx @capgo/cli@latest bundle upload --channel production
Beide Stores erlauben dies für interpretierte code, solange das Update den Hauptzweck der App nicht ändert oder ihre Zahlungsregeln umgeht. Native Änderungen (neue Plugins, neue Berechtigungen, Capacitor-Upgrades) müssen weiterhin über die Stores laufen. Mehr dazu auf Capgo Live Updates und Updater-Docs.
Füge das Plugin vor deiner ersten Store-Einreichung hinzu. Es muss im Binary enthalten sein, das Nutzer installieren, sonst erreicht dein erstes live update Nutzer erst nach einer zweiten Store-Veröffentlichung.
Automatisiere schließlich: Baue und lade bei jedem Tag von GitHub Actions oder GitLab CI hoch, schiebe Live Updates bei jedem Merge auf main, und behalte native Releases für native Änderungen bei.
Pre-Launch-Checkliste
- Apple- und Google-Accounts freigeschaltet, Verträge akzeptiert
- App funktioniert offline oder zeigt klaren Offline-Status
- Safe Areas, Tastatur und Android Back-Button berücksichtigt
- Mindestens ein paar native Features, die eine Website nicht bieten kann
- Icons, Splash, Permission Strings, Privacy Manifest
- Distribution Certificate, App Store-Profil, Upload-Keystore gesichert
- Target SDK 36 unter Android, mit Xcode 26 auf iOS gebaut
- TestFlight und Play Internal Testing auf echten Geräten durchgeführt
- Google Play Closed Test abgeschlossen (persönliche Accounts)
- Listings in beiden Stores fertig, Demo-Account hinzugefügt
- In-App-Kontolöschung, wenn Nutzer sich registrieren können
- Live-Update-Plugin im ersten Binary enthalten
Fehlerbehebung
Weißer Bildschirm beim Start. webDir zeigt auf den falschen Ordner oder du hast vergessen, bunx cap sync nach dem Build. Prüfe ios/App/App/public und android/app/src/main/assets/public enthalten index.html.
Aufrufe von API schlagen nur in der App fehl. CORS: erlaube capacitor://localhost und https://localhost. Prüfe auch, dass du nicht aufrufst http:// URLs aufrufst, die iOS standardmäßig blockiert.
Routen liefern 404 nach Refresh oder Deep Link. Verwende einen Router, der auf index.htmlzurückfällt, oder Hash-Routing für ältere Setups.
Xcode-Signierfehler. Siehe die Fehlerliste in iOS-Zertifikate und Provisioning Profiles erklärt.
Gradle-Build schlägt nach dem Upgrade fehl. Capacitor 8 benötigt Android Studio Otter (2025.2.1) oder neuer sowie JDK 21, wie in der Capacitor 8 Upgrade-Guide. Weitere Gradle-Fehler findest du unter So lösen Sie Android-Build-Fehler in Capacitor auf.
Google-Play-Upload für Target SDK abgelehnt. Setzen Sie targetSdkVersion = 36 in einem android/variables.gradle.