Skip to main content

General

Modern evergreen browsers — Chrome, Firefox, Safari, and Edge. The SDK uses ES2020 features and crypto.randomUUID() with a timestamp+random fallback for older environments.
No. Both @gbg/go-bridge-web and @gbg/go-bridge-web-react have zero runtime dependencies. React is a peerDependency for the React package.
@gbg/go-bridge-web is the framework-agnostic core (the BridgeHost class, message types, responder, error types, capability constants). @gbg/go-bridge-web-react is a React 19 adapter — a BridgeHostProvider and four hooks — that depends on the core as a peer dependency.
The core package is tiny (single-digit KB after minification + gzip); the React adapter adds little on top. Both are ESM and tree-shakeable.

Integration

Anything that lets you mount an <iframe>. React 19 has first-party support via @gbg/go-bridge-web-react. Vanilla JS, Vue, Angular, Svelte, and older React versions work with the core @gbg/go-bridge-web package.
No — the SDK accesses window and the DOM. Mark the component as client-only via "use client" (Next.js App Router), dynamic(..., { ssr: false }) (Pages Router), or your framework’s equivalent gate. The token-exchange step does run on the server.
Yes. Each BridgeHostProvider (or new BridgeHost(...)) owns its own iframe, origin allowlist, capabilities, and handler registry.
BridgeHostProvider rebuilds the underlying BridgeHost when the iframe prop transitions from null to a real element. useRef doesn’t trigger re-renders, so the provider’s effect would never fire.
Either remount the provider (key-based) or call registerCustomCapability — that one reads live on every query, no remount needed.
No. BridgeHost automatically registers CapabilityQueryHandler for the "capability.query" action.
Capability ID (e.g. camera.document) is a feature negotiation key — appears in the capabilities map. Action ID (e.g. camera.document.capture) is the specific operation — appears in useBridgeCapability(...) and inbound payload.action. Declaring the capability does not implicitly register a handler for the action; both are required.

Messaging

postMessage is reliable in-process delivery within the browser, as long as iframe.contentWindow is non-null, the listener is attached, and the envelope validates. There is no built-in retry or delivery confirmation.
No hard limit imposed by the SDK. Browsers vary in postMessage payload limits. For images, capture at moderate resolution and use JPEG at quality ~85. For multi-megabyte transfers, upload from host to your backend and pass a URL through the bridge.
Yes. postMessage delivers in send order; BridgeHost processes in arrival order.
No — outbound sends require iframe.contentWindow non-null and iframe.src set. Sends before either is ready drop with a console.warn. Wait for a journey.started event or your own readiness signal.
Events are fire-and-forget. No response expected. Either side may emit them; receivers subscribe via useBridgeHostEvent or the iframe-side SDK.

Capabilities

The journey sends a capability.query request as it loads. The host’s built-in handler responds with { environment: "web", hostVersion, capabilities }, and the journey adapts its flow accordingly.
The SDK is a routing layer — it doesn’t implement capabilities itself. Standard IDs are exported in CAPABILITY_IDS (camera.document, camera.selfie, nfc.read, biometric.auth, etc.). Web hosts realistically support camera.document, camera.selfie, and analytics.forward.
Query the browser and pass through CapabilityInfo.permissionState:
Respond with responder.unsupported("reason") or responder.error({...}). If a capability is never available on your host, declare it supported: false upfront.

Security

Messages travel over the browser’s in-process postMessage channel — they never leave the device. TLS doesn’t apply because there’s no network hop.
The bridge enforces an allowedOrigins allowlist on both inbound and outbound traffic. A script that repoints iframe.src to a hostile origin can neither send to nor receive from the host — both checks fail.
Only what the host explicitly sends via sendEvent or respond. Same-origin policy prevents the journey from reading the host’s DOM, cookies, or storage.
The journey URL is minted server-side by your backend using @gbg/go-core. Don’t hardcode it, don’t generate it in the browser, and don’t ship @gbg/go-core in your client bundle — its OAuth flow uses a client secret.

Debugging

Set a delegate:
Or read host.receivedMessages directly (capped at 200).
The transport drops on three checks: event.source mismatch, origin not in allowlist, or envelope validation failure. Common causes: trailing slashes in allowedOrigins, scheme/port mismatch, or malformed envelopes. See Troubleshooting.
Yes. Open browser DevTools and switch the document context to the iframe (Chrome: dropdown at the top of Console; Firefox: Inspector toolbar).

Next steps