Ein Agent Skill, der Claude Code die JavaScript-Bridge von WebViewGold beibringt
Ein Agent Skill ist ein Ordner mit einer SKILL.md-Datei, die Claude Code nur lädt, wenn eine Aufgabe sie braucht. Damit ist er der richtige Ort für die WebViewGold-Bridge: exakte URL-Schemes, injizierte Variablen und Plattform-Eigenheiten, die immer dann zählen, wenn der Agent ein natives Feature anfasst, und sonst nie. Hier ist ein kompletter Skill, abgeglichen mit der WebViewGold-Dokumentation und fertig für .claude/skills/.
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
9:41
Deine App
Deine AppJetzt auf dem Smartphone
App Store · Google Play Freigegeben
Warum ein Skill und keine längere CLAUDE.md
Die CLAUDE.md wird zu Beginn jeder Session gelesen, also kostet jede Zeile darin bei jeder Aufgabe Kontext, auch bei den vielen Aufgaben, die nichts mit nativen Features zu tun haben. Skills funktionieren andersherum. Claude Code behält von jedem Skill nur die kurze Beschreibung im Blick; die vollständige SKILL.md lädt erst, wenn du /webviewgold-bridge tippst oder wenn Claude merkt, dass eine Anfrage zur Beschreibung passt. Begleitdateien im Skill-Ordner laden nur, wenn die Anweisungen auf sie verweisen.
Für eine JavaScript-Bridge ist das ideal. Die Scheme-Tabelle, die Callback-Signaturen und die iOS-Workarounds sind präzises Referenzmaterial, das der Agent exakt übernehmen muss, und sie spielen keine Rolle, während er einen CSS-Bug behebt. Deine CLAUDE.md behält eine einzige Zeile ("native features: see the webviewgold-bridge skill"), und die Details leben an einem gepflegten Ort.
Ein Skill ist auch kein MCP-Server. MCP verbindet Claude mit einem Live-System wie GitHub, einer Datenbank oder einem Browser. Die Bridge braucht keine Live-Verbindung, sie braucht korrektes Wissen und eine Helper-Datei, und genau das packt ein Skill zusammen.
Die Ordnerstruktur
Drei Dateien. Nur SKILL.md ist Pflicht; die anderen beiden halten sie kurz.
text
.claude/skills/webviewgold-bridge/
├── SKILL.md rules, scheme table, patterns (loads with the skill)
├── platform-notes.md iOS vs Android differences and native switches (loads on demand)
└── templates/
└── native.ts helper module Claude copies into src/lib/
SKILL.md
Die description ist die wichtigste Zeile: Sie entscheidet, wann Claude den Skill lädt, deshalb nennt sie die Features und die Wörter, die Leute tatsächlich tippen. Sprichst du Claude meist auf Deutsch an, kannst du dort zusätzlich deutsche Begriffe wie "teilen" oder "vibrieren" ergänzen. Jedes Scheme in der Tabelle steht in der WebViewGold-Dokumentation, zum Beispiel auf den Seiten zu Push, Biometrie und Share Sheet.
markdown
---
name: webviewgold-bridge
description: Adds or debugs native iOS and Android features in this web app through the WebViewGold JavaScript bridge (URL schemes such as registerpush://, bioauth://, qrcode://, shareapp://, getonesignalplayerid://, rateapp://). Use when a task involves push notifications, Face ID, Touch ID or fingerprint login, QR or barcode scanning, the share sheet, haptics or vibration, saving images, app rating, the app version, opening app settings, or any behavior that must differ inside the native app.
---
# WebViewGold JavaScript bridge
This web app also ships as native iOS and Android apps built with WebViewGold. The apps load
the production URL in a WKWebView (iOS) or an Android WebView. Native features are triggered
by navigating to a URL scheme. Results come back as injected global variables or as calls to
global functions. There is no SDK to install and nothing to bundle.
## Rules
1. Detect the app with isNativeApp() from src/lib/native.ts. If that file does not exist,
copy templates/native.ts from this skill. Never write a second user agent check.
2. Trigger schemes only through callNative(), callNativeQuietly() or callAndRead(). Every
call needs a browser fallback: the web equivalent, or hide the control. No dead buttons.
3. Use only the schemes in the table below. For anything else, read the feature page under
https://www.webviewgold.com/docs/iOS/ or https://www.webviewgold.com/docs/android/
(full text: https://www.webviewgold.com/llms-full.txt). If it is not documented, tell
the user it is not supported. Never invent a scheme, parameter or variable name.
4. iOS processes only one location change per script run. For several data calls at once
use multiapicall://getonesignalplayerid,getappversion (comma-separated, no spaces; it
works on Android too). Fire haptics on iOS through callNativeQuietly().
5. Injected variables arrive asynchronously. Read them with readInjected() or callAndRead(),
never synchronously right after the call.
6. A scheme for a feature that is switched off in the native project does nothing. When you
add a feature, list the native settings the user must enable (see platform-notes.md).
Never edit signing, certificates, provisioning profiles or keystore settings.
7. Biometric success is a UI gate only. Sensitive actions still need a server-side check.
## Scheme reference
| Feature | Call | Result |
|---|---|---|
| Push permission prompt | registerpush:// | System permission dialog |
| Push permission status | checkNativePushPermissions:// | window.nativePushEnabled (true or false) |
| App settings | settingsapp:// | Opens the system settings of the app |
| OneSignal subscription ID | getonesignalplayerid:// | window.onesignalplayerid |
| Firebase push ID | getfirebaseplayerid:// | window.firebaseplayerid |
| Local notification | sendlocalpushmsg://push.send?s=SECONDS=msg!MESSAGE&!#TITLE&!#URL | Shown after SECONDS |
| Cancel local notifications | sendlocalpushmsg://push.send.cancel | Removes all scheduled ones |
| Biometrics | bioauth:// | iOS calls onBioAuthSuccess(), onBioAuthFailure(errorCode, errorMessage) or onBioAuthUnavailable() |
| QR code | qrcode:// | The scanned URL opens in the app |
| Barcode | barcodescanner:// | window.barcodescanresult |
| Share sheet | shareapp://message?=TEXT&url=URL | Native share dialog |
| Haptics | lighthaptic:// heavyhaptic:// successhaptic:// warninghaptic:// errorhaptic:// | Vibration; mediumhaptic:// is iOS only |
| Save image | savethisimage://?url=IMAGE_URL | Saved to the photo library |
| Rating | rateapp:// | System review dialog; the system decides whether it appears |
| App version | getappversion:// | window.versionNumber and window.bundleNumber |
## Patterns
- Push: ask after onboarding or a first success, never on the first screen. Explain in one
sentence what we will send, then call registerpush://. In settings, use pushEnabled() and
offer settingsapp:// when push is off. Save onesignalplayerid on the user profile via our API.
- Share: always encodeURIComponent TEXT and URL; share() in native.ts does it.
- QR codes: encode URLs on our own domain, because the scanned URL loads inside the app.
- Rating: only after a positive moment (order completed, task finished). Never at launch and
never in exchange for a reward.
- Version: hide UI that older app builds cannot support by checking appVersion().
## Before you finish
- Every native call sits behind isNativeApp() and has a browser fallback.
- Your summary lists each scheme you used, the native switches to enable (platform-notes.md)
and any platform-specific limits.
- Remind the user to test inside the real app on a device: push and biometrics cannot be
tested in a desktop browser.
WebViewGold hat uns die kürzeste und effizienteste Time-to-Market ermöglicht, die jemals möglich war, verglichen mit allen anderen App-Plattformen, die wir in den letzten 5 Jahren ausprobiert haben. Ich weiß nicht, warum ich euch nicht schon früher entdeckt habe, aber ich bin wirklich, wirklich froh, dass ich es getan habe. Wir nähern uns derzeit fast 6000 App-Downloads im iOS App Store & Google Play Store ohne Probleme!
Was in den nativen Projekten für jedes Feature eingeschaltet sein muss und wo sich iOS und Android unterscheiden. Claude liest diese Datei, wenn es dir sagt, welche Einstellungen du aktivieren musst. Der Hinweis zur Biometrie spiegelt den aktuellen Stand der Docs: Die iOS-Seite dokumentiert drei Callbacks, die Android-Seite nur den Prompt.
markdown
# Platform notes for the WebViewGold bridge
## User agent token
- iOS: Config.swift, useragent_iphone and useragent_ipad
- Android: Config.java, USER_AGENT
- Value: a normal mobile user agent string, a space, then WebViewGoldApp
## Push (OneSignal)
- iOS: kPushEnabled and oneSignalID in Config.swift. Set askforpushpermissionatfirstrun to
false when the web app asks later with registerpush://. The App ID needs the Push
Notifications and App Groups capabilities.
- Android: PUSH_ENABLED in Config.java, ONE_SIGNAL_APP_ID in app/build.gradle.
- Firebase instead of OneSignal: getfirebaseplayerid:// and window.firebaseplayerid.
## Variables without a call
- iOS autoInjectVariable, Android AUTO_INJECT_VARIABLES: values such as the push ID and the
app version are injected automatically. readInjected() works either way.
## Biometrics
- iOS: add "Privacy - Face ID Usage Description" to Info.plist. Callbacks:
onBioAuthSuccess(), onBioAuthFailure(errorCode, errorMessage), onBioAuthUnavailable().
- Android: the system BiometricPrompt, which may fall back to PIN or pattern. The Android
docs describe the prompt but not the three callbacks: test on a device before relying on
them, and keep a fallback.
- enableBioMetricAuth (both platforms) is a separate app lock on every launch and is
independent of bioauth://.
## Camera features (qrcode://, barcodescanner://)
- iOS: camera usage description in Info.plist; qrcodelinks in Config.swift decides where
scanned URLs open.
- Android: requireCamera and QR_CODE_URL_OPTIONS in Config.java.
## Haptics
- mediumhaptic:// exists on iOS only. Use lighthaptic:// or heavyhaptic:// on Android.
## Downloads
- savethisimage://?url=... saves an image. Other files download natively by extension:
extentionARY (Config.swift) and downloadableExtension (Config.java).
## Rating
- rateapp:// shows the system review dialog, which the system rate-limits.
iOS alternative: showcustomrateappdialog and ratemyappurl in Config.swift.
## Documentation
- iOS: https://www.webviewgold.com/docs/iOS/
- Android: https://www.webviewgold.com/docs/android/
- Full text for agents: https://www.webviewgold.com/llms-full.txt
templates/native.ts
Der Helper, den Claude laut Skill kopieren soll. Er ist die einzige Stelle, die das User-Agent-Token kennt, und er regelt drei Details, die Agenten meist übersehen: den stillen iframe-Aufruf für Haptik aus den iOS-Docs zur Haptik, nur eine Location-Änderung pro Skriptlauf auf iOS (siehe MultiAPICall) und das Leeren einer veralteten Variable, bevor eine frische gelesen wird.
typescript
// templates/native.ts
// Copied into src/lib/native.ts by the webviewgold-bridge skill.
// The only file that knows how the web app detects the WebViewGold apps.
// Set in Config.swift (useragent_iphone, useragent_ipad) and Config.java (USER_AGENT)
const TOKEN = "WebViewGoldApp";
export function isNativeApp(): boolean {
return typeof navigator !== "undefined" && navigator.userAgent.includes(TOKEN);
}
export function isAndroidApp(): boolean {
return isNativeApp() && /Android/i.test(navigator.userAgent);
}
export function isIOSApp(): boolean {
return isNativeApp() && !isAndroidApp();
}
// Navigate to a scheme. Returns false in normal browsers so callers can fall back.
export function callNative(scheme: string): boolean {
if (!isNativeApp()) return false;
window.location.href = scheme;
return true;
}
// Fire-and-forget call through a temporary iframe, so it does not cancel a
// navigation in progress (the technique from the WebViewGold iOS haptics docs).
export function callNativeQuietly(scheme: string): boolean {
if (!isNativeApp()) return false;
const frame = document.createElement("iframe");
frame.style.display = "none";
frame.src = scheme;
document.body.appendChild(frame);
frame.remove();
return true;
}
// Poll for a global variable the app injects (onesignalplayerid, nativePushEnabled ...)
export function readInjected<T = unknown>(name: string, timeoutMs = 3000): Promise<T> {
return new Promise((resolve, reject) => {
const started = Date.now();
const tick = () => {
const value = (window as any)[name];
if (value !== undefined) return resolve(value as T);
if (Date.now() - started > timeoutMs) return reject(new Error(name + " was not injected"));
setTimeout(tick, 100);
};
tick();
});
}
// Call a scheme and read a fresh result; clears a stale value first.
export async function callAndRead<T = unknown>(scheme: string, name: string, timeoutMs = 3000): Promise<T | null> {
if (!isNativeApp()) return null;
try { delete (window as any)[name]; } catch { /* variable not deletable, keep polling */ }
window.location.href = scheme;
return readInjected<T>(name, timeoutMs).catch(() => null);
}
export type Haptic = "light" | "heavy" | "success" | "warning" | "error";
export function haptic(kind: Haptic): void {
const scheme = kind + "haptic://";
if (isIOSApp()) callNativeQuietly(scheme);
else callNative(scheme);
}
export function share(text: string, url: string): boolean {
return callNative("shareapp://message?=" + encodeURIComponent(text) + "&url=" + encodeURIComponent(url));
}
export function pushEnabled(): Promise<boolean | null> {
return callAndRead<boolean>("checkNativePushPermissions://", "nativePushEnabled", 2000);
}
export function appVersion(): Promise<string | null> {
return callAndRead<string>("getappversion://", "versionNumber", 2000);
}
Den Skill installieren und testen
Funktioniert genauso im Terminal, in den IDE-Erweiterungen und in Cloud-Sessions.
Den Ordner anlegen
Lege im Root des Repositorys .claude/skills/webviewgold-bridge/ mit den drei Dateien oben an und committe sie. Für einen Skill, den du in all deinen Projekten haben willst, nimm stattdessen ~/.claude/skills/webviewgold-bridge/.
Auf deine App zuschneiden
Lösche Tabellenzeilen für Features, die du in den nativen Projekten nicht eingeschaltet hast. Ein Scheme für ein deaktiviertes Feature bewirkt zur Laufzeit nichts, und ein Agent, der es in der Tabelle sieht, baut es bereitwillig ein.
Prüfen, ob Claude ihn sieht
Tippe in Claude Code / und such nach webviewgold-bridge, oder frag "Welche Skills kannst du in diesem Projekt nutzen?". Fehlt er, stell sicher, dass das Frontmatter in der allerersten Zeile von SKILL.md beginnt.
Ihn von selbst auslösen lassen
Bitte um ein Feature, ohne den Skill zu nennen: "Füge auf der Rezeptseite einen Teilen-Button hinzu." Claude sollte den Skill laden, shareapp:// über share() nutzen und den Button zum Link-Kopieren als Fallback für den Browser behalten.
Ihn gezielt starten, wenn du willst
/webviewgold-bridge füge nach dem Checkout Erfolgs-Haptik hinzu lädt den Skill und übergibt den Rest der Zeile als Aufgabe.
Prüfen, deployen, auf dem Gerät testen
Prüfe jeden Aufruf auf den Guard isNativeApp() und lies die Liste der nativen Schalter, die Claude meldet. Dann deploye und teste in der echten App; Push und Face ID funktionieren nicht in einem Desktop-Browser.
Lass Claude Code den Skill auf deine App zuschneiden
Nutze das, statt die Dateien von Hand zu kopieren, wenn der Skill nur die Features enthalten soll, die du wirklich aktiviert hast.
In Claude Code im Projekt-Root einfügen
Lege für dieses Repository einen Agent Skill unter .claude/skills/webviewgold-bridge/ an. Unsere Web-App läuft auch in nativen iOS- und Android-Apps, die mit WebViewGold gebaut sind; native Features werden über URL-Schemes ausgelöst und geben Werte über injizierte JavaScript-Variablen oder globale Callback-Funktionen zurück.
1. Lies Config.swift und Config.java (in native/ios und native/android, passe das an, falls abweichend) und liste auf, welche nativen Features tatsächlich eingeschaltet sind.
2. Öffne für jedes aktivierte Feature die passende Dokumentationsseite unter https://www.webviewgold.com/docs/iOS/ und https://www.webviewgold.com/docs/android/ und übernimm das exakte Scheme, die Parameter und die Rückgabevariablen. Lass alles weg, was du in der Dokumentation nicht findest, und liste diese Punkte separat für mich auf.
3. Schreib SKILL.md mit Frontmatter (name: webviewgold-bridge und eine description, die die Features und die Wörter nennt, die ein Nutzer tippen würde), kurzen Regeln (isNativeApp-Guard, Fallback für den Browser, multiapicall auf iOS für mehrere Datenaufrufe, asynchrone injizierte Variablen, keine erfundenen Schemes), einer Scheme-Tabelle und einer Checkliste für den Abschluss einer Aufgabe.
4. Schreib die Unterschiede zwischen iOS und Android sowie die nötigen Einstellungen in Config.swift, Config.java, Info.plist und AndroidManifest.xml in platform-notes.md.
5. Leg das Helper-Modul in templates/native.ts ab, mit isNativeApp, callNative, callNativeQuietly (iframe), readInjected und callAndRead.
Halte SKILL.md unter 150 Zeilen und zeig mir jede Datei vor dem Speichern.
Skill, CLAUDE.md, Subagent, Command, Hook oder MCP?
Mechanismus
Lädt wann
Einsatz in einem WebViewGold-Projekt
CLAUDE.md
In jeder Session
Kurze, dauerhafte Regeln: Die App läuft in einer WebView, die Store-Regeln, die geschützten Routen
Skill (SKILL.md)
Wenn eine Aufgabe passt, oder per /name
Referenzwissen und Templates, etwa dieser Bridge-Skill
Subagent
Wenn Claude delegiert
Arbeit, die einen eigenen Kontext und eine strenge Rolle braucht, etwa der Store-Review-Checker
Command
Wenn du ihn tippst
Ein Ablauf, den du bewusst startest, etwa /release-check
Hook
Bei einem Lifecycle-Event, jedes Mal
Regeln, die auch dann gelten müssen, wenn das Modell anderer Meinung ist, etwa keine localhost-URL in den Config-Dateien
MCP-Server
Wenn seine Tools aufgerufen werden
Live-Systeme: GitHub, deine Datenbank, ein Browser für Screenshots
Fallstricke
Eine vage description. "WebViewGold helper" löst nie aus. Nenn die Features und Verben, die Leute verwenden: Push, Face ID, scannen, teilen, vibrieren, die App bewerten.
Zwei Quellen der Wahrheit. Steht die Scheme-Tabelle auch in der CLAUDE.md, veraltet eine der beiden Kopien. Halte die Tabelle im Skill und lass die CLAUDE.md darauf verweisen.
Ein Skill, der zum Handbuch wächst. Halte SKILL.md kurz und verschiebe Details in Begleitdateien. Claude liest, worauf die Anweisungen verweisen, und zwar dann, wenn es das braucht.
Den Gerätetest auslassen. Der Skill macht den Code korrekt; erst die echte App beweist, dass das Feature eingeschaltet, erlaubt und funktionsfähig ist.
Veraltet nach einem WebViewGold-Update. Wenn du auf eine neue WebViewGold-Version umsteigst, lass Claude die Tabelle erneut mit der Dokumentation und den neuen Config-Dateien abgleichen.
Skills installieren, die du nicht gelesen hast. Skills können Skripte mitbringen, die Claude ausführen darf. Lies einen Skill von Dritten, bevor du ihn hinzufügst, so wie du es bei einer Abhängigkeit tun würdest.
Häufig gestellte Fragen
Funktionieren Skills in Claude Code im Web und in GitHub Actions?
Ja. Projekt-Skills in .claude/skills/ sind Teil des Repositorys, also laden Cloud-Sessions sie, und die Claude Code GitHub Action kann einen Skill ausführen, wenn der Workflow zuerst das Repository auscheckt und /skill-name als Prompt übergibt.
Lädt Claude den Skill automatisch?
Wenn eine Anfrage zur description passt, ja. Du kannst ihn auch selbst mit /webviewgold-bridge starten. Soll er nur manuell laufen, ergänze disable-model-invocation: true im Frontmatter.
Was ist der Unterschied zum Guide zur JavaScript-Bridge?
Der Guide erklärt dir die Bridge und gibt dir einen Prompt für eine einmalige Integration. Der Skill ist die dauerhafte Version für den Agenten: Er lädt von selbst, sobald eine spätere Aufgabe ein natives Feature berührt, auch Monate nachdem du die Details vergessen hast.
Können Cursor oder Codex dieselbe SKILL.md nutzen?
SKILL.md folgt dem offenen Agent-Skills-Format, und mehrere andere Agenten können es lesen, aber jedes Tool sucht in seinem eigenen Ordner. Schau in die Dokumentation des jeweiligen Tools oder nutz die Templates für Cursor Rules oder AGENTS.md in diesem Bereich.
Warum funktioniert ein Scheme auf Android, aber nicht auf iOS?
Meist, weil im selben Skript mehrere Zuweisungen an window.location.href liefen. iOS verarbeitet nur eine; fasse Datenaufrufe mit multiapicall:// zusammen und löse Haptik über einen temporären iframe aus, so wie es der Helper tut.
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.
Kein Mac, kein Xcode, kein Android Studio: Du konfigurierst im Browser, wir bauen beide Apps in der Cloud und übergeben sie an App Store Connect und die Play Console.
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.
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.