Zum Inhalt springen
WebViewGold Vibe Coding in den App Store
Deutsch
WebViewGold holen

Claude Code + Zuverlässigkeit

Offline-Screen und Fehlerzustände mit Claude Code: was das App-Review testet und wie du bestehst

Ein Reviewer schaltet den Flugmodus ein, tippt herum und schaltet ihn wieder aus. Zeigt deine App dabei eine weiße Seite, einen rohen Fehler oder einen Spinner, der nie aufhört, ist das eine Ablehnung nach Richtlinie 2.1 bzw. wegen fehlerhafter Funktionalität. WebViewGold fängt fehlgeschlagene Seitenladevorgänge mit einem nativen Offline-Screen ab; alles, was in deiner laufenden Web-App passiert, ist Sache deines Codes. So baut Claude Code diesen Teil, und so testest du ihn wie ein Reviewer.

Ab $109 einmalig pro Plattform, oder unser Team erledigt alles ab $698.

  • Genehmigungsgarantie – oder Geld zurück innerhalb von 14 Tagen
  • Kein Programmieren nötig
  • Einmalzahlung, kostenlose Updates
  • 24/7 Support von echten Menschen
  • Made in Germany seit 2014 · ISO 27001

Zwei Ebenen: die native Hülle und deine laufende App

Die Hülle. Wenn die WebView eine Seite nicht laden kann, zeigt WebViewGold statt einer Fehlerseite seinen nativen Offline-Screen. Auf iOS setzt du die Texte mit offlinetitle, offlinemsg, screen1, screen2 und offlinebuttontext, und offlinescreenautoretry versucht es jede Sekunde erneut, ganz ohne Antippen. Auf Android setzt du den Hintergrund mit OFFLINE_SCREEN_BACKGROUND_COLOR; die Texte der App liegen in strings.xml. Wenn du mehr willst, können beide Plattformen offline eine mitgelieferte lokale HTML-Seite anzeigen (offlinelocalhtmlswitch auf iOS, FALLBACK_USE_LOCAL_HTML_FOLDER_IF_OFFLINE auf Android), mit einem Button „Erneut versuchen“, der reconnect:// aufruft und die letzte Online-URL neu lädt (Reconnect API).

Deine App. Eine Single-Page-App, die bereits läuft, löst keine Seitenladevorgänge aus, wenn die Verbindung abbricht. Ihre Fetches scheitern innerhalb der Seite, und nur dein Code kann etwas Sinnvolles anzeigen: ein Offline-Banner, einen Fehlerzustand mit „Erneut versuchen“, ein Timeout statt eines endlosen Spinners. Daher kommen die meisten Offline-Ablehnungen, und genau diesen Teil baut Claude Code unten. Der Hub zum Offline-Modus vergleicht die drei Stufen der Offline-Unterstützung.

Reviewer wenden Richtlinie 2.1 an (Vollständigkeit der App: Abstürze, kaputte Screens, Platzhalterinhalte), und Google wendet seine Regeln zu fehlerhafter Funktionalität an. Keiner von beiden erwartet, dass deine App komplett offline funktioniert; beide erwarten, dass sie sagt, was gerade passiert, und sich wieder fängt.

Was Claude Code übernimmt und was du machst

Claude Code

Schreibt den Online-Hook, den Fetch-Wrapper, jeden Lade-, Leer- und Fehlerzustand, die Error Boundary, die Fallback-Seite und Playwright-Tests, die Offline-Betrieb und Serverfehler simulieren, und führt sie dann aus.

Du

Setzt die nativen Offline-Texte und -Farben, kopierst die Fallback-Seite in beide WebViewGold-Projekte, schaltest das Fallback ein, wenn du es willst, und baust einmal.

Der Reviewer-Test

Flugmodus beim Start und mitten in der Session, ein langsames Netz und eine kaputte API, auf echten Geräten. Das ist der einzige Test, der dem entspricht, was das App-Review macht.

Fehlerfälle und wer sie abfängt

SituationZuständigWas der Nutzer sehen sollte
Keine Verbindung beim App-StartWebViewGold-Offline-Screen oder lokales FallbackDeine Nachricht im eigenen Branding und „Erneut versuchen“
Verbindung bricht während der Nutzung abDeine Web-AppEin schmales Offline-Banner; Aktionen, die das Netz brauchen, deaktiviert oder in einer Warteschlange
Sehr langsames NetzDeine Web-AppSkeletons, dann nach etwa 10 bis 15 Sekunden ein Timeout mit „Erneut versuchen“
API liefert 500Deine Web-AppEin verständlicher Satz und „Erneut versuchen“; kein Stacktrace, kein JSON
Session abgelaufenDeine Web-AppZurück zum Login mit kurzer Erklärung, danach zurück zur ursprünglichen Seite
Unbekannte RouteDeine Web-AppEine Not-found-Seite im App-Stil mit Home-Button
Geplante WartungDeine Web-AppEine Wartungsseite, die du ohne Deploy einschalten kannst

Großartige Möglichkeit, eine Web-App in eine native App zu verwandeln! Schnelle Umsetzung und ein toller Weg, Apps in die App Stores zu bringen, ohne eine komplett native App entwickeln zu müssen!

Kevin Joling · FlightConnections & TrainConnections · Trustpilot

Der Claude Code Prompt

Die Playwright-Tests in Punkt 7 machen das wiederholbar: Claude Code schreibt sie, führt sie über sein Bash-Tool aus und behebt, was fehlschlägt.

In Claude Code einfügen
Reviewer testen unsere App im Flugmodus und in schlechten Netzen. Die App läuft in nativen iOS- und Android-Apps, die mit WebViewGold gebaut sind. Wenn ein Seitenladevorgang scheitert, zeigt der Wrapper seinen nativen Offline-Screen, aber sobald unsere Single-Page-App läuft, werden fehlgeschlagene Fetches und Routenwechsel nur von unserem Code behandelt. Mach jeden Fehlerfall sichtbar und behebbar.

1. src/lib/use-online.ts: ein Hook auf Basis der Window-Events online und offline. Zeige offline ein schmales Banner unterhalb der Safe Area: „Du bist offline. Wir laden deine Daten neu, sobald du wieder online bist.“ Blende es aus, wenn die Verbindung zurück ist, und lade die sichtbaren Queries neu.
2. src/lib/fetch-json.ts: ein einziger Fetch-Wrapper mit 12 Sekunden Timeout (AbortController), einem NetworkError für offline, Timeout und fehlgeschlagene Requests sowie einer Weiterleitung auf /login?reason=expired bei 401, die nach dem Login zum ursprünglichen Pfad zurückführt. Ersetze direkte fetch-Aufrufe durch ihn.
3. Jeder Screen, der Daten lädt, bekommt ein Lade-Skeleton, einen Leerzustand mit einer hilfreichen Aktion und einen Fehlerzustand mit einem verständlichen Satz und einem Button „Erneut versuchen“. Keine rohen Fehlermeldungen, Statuscodes oder Stacktraces in der UI.
4. Aktionen, die das Netz brauchen, sind offline deaktiviert und zeigen „Warte auf Verbindung“, oder sie werden in eine Warteschlange gestellt und gesendet, sobald die Verbindung zurück ist. Was der Nutzer eingegeben hat, darf nie verloren gehen.
5. Eine Root-Error-Boundary mit freundlichem Fallback und einem Button „Neu laden“, eine Not-found-Seite im App-Stil mit Home-Button und eine Seite /maintenance, die wir über eine Umgebungsvariable einschalten können.
6. Kein Spinner darf ewig laufen: Jeder Ladezustand endet in Inhalt, Leerzustand oder Fehler.
7. Playwright-Tests, die mit context.setOffline(true) das Banner, den Fehlerzustand mit „Erneut versuchen“ und die Erholung nach dem Wiederherstellen der Verbindung prüfen, plus ein Test, der eine 500-Antwort der API mockt. Führe sie aus und behebe Fehlschläge.
8. public/offline-fallback/index.html: eine eigenständige Seite (Inline-CSS, keine externen Schriften, Skripte oder Bilder) in unseren Markenfarben mit einer kurzen Nachricht und einem Button „Erneut versuchen“, der zu reconnect:// navigiert. Ich kopiere sie in die WebViewGold-Projekte.

Liste jeden Screen auf, den du angefasst hast, und alles, was du nicht testen konntest.

Der Online-Hook und der Fetch-Wrapper

Klein genug, um es in einem Rutsch zu prüfen. Beachte: Dass navigator.onLine true ist, beweist nicht, dass das Internet funktioniert (denk an Hotel-WLAN), deshalb werden auch fehlgeschlagene Requests als Netzwerkfehler behandelt.

typescript
// src/lib/use-online.ts
import { useEffect, useState } from "react";

export function useOnline() {
  const [online, setOnline] = useState(typeof navigator === "undefined" ? true : navigator.onLine);
  useEffect(() => {
    const up = () => setOnline(true);
    const down = () => setOnline(false);
    window.addEventListener("online", up);
    window.addEventListener("offline", down);
    return () => {
      window.removeEventListener("online", up);
      window.removeEventListener("offline", down);
    };
  }, []);
  return online;
}

// src/lib/fetch-json.ts
export class NetworkError extends Error {}

export async function fetchJson<T>(url: string, init: RequestInit = {}, timeoutMs = 12000): Promise<T> {
  if (typeof navigator !== "undefined" && !navigator.onLine) throw new NetworkError("offline");
  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), timeoutMs);
  try {
    const res = await fetch(url, { ...init, signal: ctrl.signal });
    if (res.status === 401) {
      window.location.href = "/login?reason=expired&next=" + encodeURIComponent(location.pathname);
      throw new Error("unauthorized");
    }
    if (!res.ok) throw new Error("HTTP " + res.status);
    return (await res.json()) as T;
  } catch (e) {
    if (e instanceof DOMException && e.name === "AbortError") throw new NetworkError("timeout");
    if (e instanceof TypeError) throw new NetworkError("network"); // Request hat den Server nie erreicht
    throw e;
  } finally {
    clearTimeout(timer);
  }
}

Eine mitgelieferte Fallback-Seite mit reconnect://

Alles inline, weil diese Seite genau dann angezeigt wird, wenn sich nichts herunterladen lässt. Kopiere sie in den lokalen HTML-Ordner jedes WebViewGold-Projekts, wie in der iOS-Setup-Anleitung und der Android-Setup-Anleitung beschrieben (Option C). Passe die Texte an die Sprache deiner App an.

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <title>Offline</title>
  <style>
    body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 24px;
           box-sizing: border-box; text-align: center; background: #0f172a; color: #e2e8f0;
           font-family: -apple-system, system-ui, sans-serif; }
    h1 { font-size: 22px; margin: 0 0 8px; }
    p { margin: 0; line-height: 1.5; color: #94a3b8; }
    button { margin-top: 24px; min-height: 48px; padding: 0 28px; border: 0; border-radius: 12px;
             background: #38bdf8; color: #0f172a; font-size: 17px; font-weight: 600; }
  </style>
</head>
<body>
  <main>
    <h1>You are offline</h1>
    <p>We will take you back to where you were as soon as the connection returns.</p>
    <button type="button" onclick="window.location.href='reconnect://'">Try again</button>
  </main>
</body>
</html>

Die native Seite einrichten

Zehn Minuten pro Projekt, plus ein Build.

  1. Den Offline-Screen branden

    iOS: Schreib offlinetitle, offlinemsg, screen1, screen2 und offlinebuttontext im Ton deiner App und setze offlinescreenautoretry auf true. Android: Setze OFFLINE_SCREEN_BACKGROUND_COLOR und prüf die Offline-Formulierungen unter den Texten der App in strings.xml.

  2. Optional: das mitgelieferte Fallback

    Kopiere die Seite oben in den lokalen HTML-Ordner und schalte offlinelocalhtmlswitch (iOS) oder FALLBACK_USE_LOCAL_HTML_FOLDER_IF_OFFLINE (Android) ein; lass uselocalhtmlfolder / USE_LOCAL_HTML_FOLDER auf false, damit die Remote-URL die primäre Quelle bleibt.

  3. Lade-Feedback

    Wähle das native Ladesymbol oder den Fortschrittsbalken (useLoadingSign, useLoadingProgressBar, loadingIndicatorColor auf iOS; ACTIVATE_PROGRESS_BAR auf Android). Bei langen Serveroperationen kann deine App den nativen Spinner mit spinneron:// einblenden und mit spinneroff:// wieder ausblenden.

  4. Prompt ausführen und deployen

    Prüf das Diff, führ die Playwright-Tests einmal selbst aus, deploye. Der Web-Teil kommt sofort bei bestehenden App-Installationen an.

  5. Einmal bauen

    Die Offline-Texte und die Fallback-Seite sind Teil des nativen Builds. Wenn unser Team das einrichten und beide Apps bauen soll, deckt der Full Service das ab.

Teste es wie ein Reviewer

  • Kaltstart im Flugmodus: Der native Offline-Screen (oder deine Fallback-Seite) erscheint mit deinen Texten. Schalte den Flugmodus aus und tippe auf „Erneut versuchen“: Die App lädt.
  • Nutze die App und schalte dann den Flugmodus ein: Das Banner erscheint, Buttons, die das Netz brauchen, zeigen „Warte auf Verbindung“, nichts wird weiß. Schalte ihn aus: Das Banner verschwindet, und die Daten aktualisieren sich.
  • Simuliere ein schlechtes Netz: auf dem iPhone mit dem Network Link Conditioner unter Einstellungen → Entwickler (sichtbar, sobald das Gerät einmal mit Xcode verwendet wurde), auf Android mit den Einstellungen für die Netzwerkgeschwindigkeit eines Emulators. Skeletons erscheinen, dann Inhalt oder ein Timeout mit „Erneut versuchen“.
  • Lass ein Preview-Deployment auf eine falsche API-URL zeigen: Jeder Screen zeigt seinen Fehlerzustand mit „Erneut versuchen“, keiner zeigt rohes JSON.
  • Melde dich in einem anderen Tab ab oder lass die Session ablaufen: Die App kehrt mit einer kurzen Erklärung zum Login zurück und danach zur ursprünglichen Seite.
  • Öffne eine Route, die es nicht gibt: Es erscheint eine Not-found-Seite im App-Stil mit Home-Button.
  • Schick die App für eine halbe Stunde in den Hintergrund und kehr zurück: Sie funktioniert noch oder lädt sauber neu (zieh autoRefreshEnabled / AUTO_REFRESH_ENABLED in Betracht, wenn deine Daten veralten, und teste, dass halb ausgefüllte Formulare dabei nicht verloren gehen).

Stolperfallen

  • Endlose Spinner. Jeder Request braucht ein Timeout. Ein Spinner, der nie endet, wirkt auf Reviewer wie ein Hänger.
  • Eine Fallback-Seite, die etwas nachlädt. Webfonts, CSS vom CDN oder Bilder von deinem Server gibt es offline nicht. Pack alles inline.
  • Offline-Unterstützung auf einem Service Worker aufbauen. Verlass dich in der iOS-App nicht darauf: WKWebView aktiviert Service Worker nur in bestimmten Konfigurationen. Der native Offline-Screen und das mitgelieferte Fallback sind die verlässlichen Ebenen.
  • Den Reviewer aussperren. Geoblocking, Firewall-Regeln gegen Rechenzentrums-IPs oder eine aggressive Bot-Abwehr lassen deine API ausgerechnet bei Apple und Google scheitern. Prüf deine Regeln für die Regionen, aus denen Reviewer testen.
  • Platzhalter-Screens. Coming-soon-Seiten und tote Buttons sind ebenfalls Probleme nach Richtlinie 2.1. Bitte den Agenten, sie aufzulisten, wenn er ohnehin jeden Screen anfasst.

Häufig gestellte Fragen

Muss meine App komplett offline funktionieren?

Nein. Reviewer erwarten eine klare Meldung und eine funktionierende Wiederherstellung, keine Offline-Features. Vollständige Offline-Nutzung braucht eine mitgelieferte lokale Version oder eine App, die für Offline-Daten konzipiert ist.

Warum erscheint der native Offline-Screen nicht, wenn die Verbindung mitten in der Session abbricht?

Weil in diesem Moment nichts geladen wird. Eine laufende Single-Page-App scheitert nur an ihren eigenen Fetches, also muss dein Code das Banner und die Fehlerzustände anzeigen.

Was genau macht reconnect://?

Es lädt die letzte URL neu, die erfolgreich geladen wurde, bevor die App auf die Offline-Seite umgeschaltet hat. Ist die Verbindung immer noch weg, erscheint wieder die Fallback-Seite.

Kann Claude Code den Flugmodus selbst testen?

Es kann mit Playwright im Browser Offline-Betrieb simulieren (context.setOffline) und Serverfehler mocken, was deinen Web-Code abdeckt. Der native Offline-Screen und das echte Netzwerkverhalten brauchen trotzdem einen Test auf dem Handy.

Wo sollte das Offline-Banner erscheinen?

Unterhalb der Statusleiste und der Safe Area, über dem Inhalt, aber nie über primären Buttons. Ein schmaler Balken oben ist die Konvention, die Nutzer kennen.

Drei Wege, deine App in die Stores zu bringen

Gleiches Ergebnis, unterschiedlich viel Arbeit auf deiner Seite. Alle drei kommen mit Genehmigungsgarantie und 24/7 Support von echten Menschen.

Selbst machen

$109 pro Plattform, einmalig

Die WebViewGold-Lizenz: ein fertiges Xcode- oder Android-Studio-Projekt. URL einfügen, Name und Icon setzen, Features einschalten, bauen und einreichen. Kostenlose Updates für immer.

Pakete auf der Hauptseite ansehen

Full Service

$698 pro Plattform $798

Schick uns deine URL und dein Icon. Unser Team konfiguriert, baut und liefert deine App innerhalb von 72 Stunden, White-Label, inklusive Quellprojekten. Beide Plattformen für $1,158.

Full-Service-Details Powered by WeSetupYourWebViewApp

Winter-Sale-Preise gültig bis 31. Dezember 2026.

Bereit, deine App zu veröffentlichen?

App Store & Google Play Genehmigungsgarantie – oder Geld zurück innerhalb von 14 Tagen

Lieber abgeben? Full Service: Wir konfigurieren, bauen und liefern innerhalb von 72 Stunden, ab $698 pro Plattform. Fragen? Chatte mit uns – 24/7.

Erstattungen erfolgen zu den in unseren FAQ genannten Bedingungen: eine nicht inhaltsbedingte Ablehnung durch Apple und/oder Google, geltend gemacht innerhalb von 14 Tagen nach dem Kauf.