npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gbg/go-bridge-web

v0.2.1

Published

Host-page SDK for embedding GBG GO identity verification journeys in a web app via iframe. Framework-agnostic core with a type-safe bridge messaging protocol.

Downloads

965

Readme

@gbg/go-bridge-web

Host-page SDK for embedding GBG GO identity verification journeys in a web application via iframe. Framework-agnostic, zero dependencies, with a typed bridge messaging protocol over postMessage.

Using React? @gbg/go-bridge-web-react wraps this package with a Provider and hooks.

Prerequisites

You need a GBG GO agreement and a configured journey. The URL you load into the iframe — and therefore the origin you allowlist — comes from your GBG GO journey configuration; your GBG integration contact can provide it, along with the set of bridge actions your specific journey sends.

Installation

npm install @gbg/go-bridge-web

Quick start

<iframe
  id="journey"
  src="https://your-journey-url.example/…"
  sandbox="allow-scripts allow-same-origin allow-forms"
  allow="camera"
></iframe>
import { BridgeHost } from '@gbg/go-bridge-web';

const iframe = document.querySelector<HTMLIFrameElement>('#journey');
if (!iframe) throw new Error('journey iframe not found');

const host = new BridgeHost({
  iframe,
  // Origins the journey is served from. Required, must be non-empty.
  allowedOrigins: ['https://your-journey-origin.example'],
  // Identifies your host app in capability.query responses.
  hostVersion: 'my-app-1.0.0',
  // Capabilities your page offers the journey (all optional).
  capabilities: {
    'analytics.forward': { supported: true, version: '1.0' },
  },
});

// Handle requests the journey sends to your page.
host.registerHandler('analytics.forward', {
  handle: (request, responder) => {
    const { data } = request.payload as { data: Record<string, unknown> };
    myTelemetry.track(data); // your analytics client — not part of the SDK
    responder.success({});
  },
});

// When the host is no longer needed:
host.detach();

Two things to know before your first send:

  • Constructing the host appends bridge parameters to the iframe's src (see Security notes); if src was already set, this reloads the iframe once.
  • Outbound messages are not queued. A send before iframe.src is set is dropped with a console warning; a send after src is set but before the journey has finished loading can be silently discarded by the browser. Send events only once the journey is running — e.g. after its first event reaches you:
let journeyReady = false;
host.delegate = {
  onMessage: (h, message) => {
    if (message.type === 'event' && !journeyReady) {
      journeyReady = true;
      h.sendEvent('host.locale.update', { locale: 'en-GB' });
    }
  },
};

How it works

The SDK exchanges JSON messages with the embedded journey over window.postMessage. Every message carries a protocol version, a correlationId, a type, and a payload:

  • request (journey → host) — the journey asks the host to do something, e.g. forward an analytics event. The host answers via a response with the same correlationId.
  • response (host → journey) — terminal statuses are success, error, cancelled, and unsupported; acknowledged is an interim status for long-running work.
  • event (either direction) — fire-and-forget notifications such as journey lifecycle changes or host locale updates. See BridgeActions for the well-known action identifiers.

Messages arriving with a different protocol version are processed anyway, with a console warning. The current version is exported as BridgeHost.PROTOCOL_VERSION.

Capability discovery

The journey discovers what your page supports by sending a capability.query request. The SDK answers this automatically from the capabilities map you pass to the constructor plus anything you add later with registerCustomCapability(id, version?, handler?) — for ids present in both, the constructor map takes precedence. Well-known capability identifiers are exported as CAPABILITY_IDS (camera.document, camera.selfie, nfc.read, biometric.auth, device.attestation, location.gps, storage.secure, analytics.forward).

Note: only the supported, version, and permissionState fields of a CapabilityInfo are transmitted to the journey; constraints is host-side only.

Handling requests

Which request actions (if any) a journey sends depends on how that journey is configured — confirm the set with your GBG integration contact. Register a handler per action with registerHandler(action, handler). A handler receives the raw BridgeMessage and a BridgeResponder:

host.registerHandler('camera.document.capture', {
  handle: async (request, responder) => {
    responder.acknowledge(); // interim: tell the journey work has started
    try {
      // captureDocument() is your implementation — the SDK does not
      // provide capture UI.
      const result = await captureDocument();
      responder.success({ imageRef: result.ref });
    } catch (err) {
      responder.error({
        code: 'INTERNAL_ERROR',
        message: String(err),
        recoverable: false,
      });
    }
  },
});

A responder sends at most one terminal response — after success / error / cancelled / unsupported, further calls are no-ops. If a handler throws (or its returned promise rejects) before responding, the SDK sends an error response on its behalf (code HANDLER_FAILURE, which journeys surface as an internal error) so the journey isn't left waiting.

Requests with no registered handler are queued on host.pendingRequests (up to 50; beyond that they are dropped and reported via the delegate's onError) and surfaced through the delegate's onUnhandledRequest; you can answer a queued request later with host.respond({ correlationId, status, data }).

Watching traffic and errors

Pass a BridgeHostDelegate to observe traffic and failures:

const host = new BridgeHost({
  iframe,
  allowedOrigins: ['https://your-journey-origin.example'],
  delegate: {
    onMessage: (host, message) => console.debug('in', message),
    onMessageSent: (host, message) => console.debug('out', message),
    onUnhandledRequest: (host, request) => console.warn('unhandled', request),
    onError: (host, error) => console.error(error),
  },
});

onError fires for handler throws (before a response has been sent), delegate throws, and postMessage exceptions. Sends dropped for other reasons (no src yet, origin not allowlisted) surface as console warnings only, and sends after detach() are dropped silently.

host.receivedMessages (the last 200 inbound messages), host.pendingRequests, and host.lastError expose the same information for polling-style debugging. Note the buffering: message payloads stay in your page's memory until trimmed or the host is released.

Security notes

  • allowedOrigins is your trust boundary. Inbound messages from any other origin are ignored, and outbound sends verify the iframe's current src origin against the allowlist — so a repointed iframe cannot receive bridge payloads. Entries must be http(s) origins; wildcards such as * are rejected at construction, and URL-shaped entries are normalized down to their origin.
  • Sandbox the iframe yourself. The SDK does not set sandbox attributes. sandbox="allow-scripts allow-same-origin allow-forms" is a reasonable starting point. Because the journey is served cross-origin, allow-same-origin relaxes the sandbox only to the journey's origin (which needs its own storage and cookies), not to yours. Add allow-modals / allow-popups only if your journey needs them.
  • Grant camera access. Journeys that capture documents or selfies in the browser call getUserMedia inside the iframe, which a cross-origin iframe can only do with a Permissions-Policy grant: set allow="camera" on the iframe (and microphone if your journey records audio). Without it, capture fails inside the journey.
  • URL parameters. When the host attaches, the SDK appends gbggoSource (SDK name/version and embedding host) and gbggoHostOrigin (your page's origin) query parameters to the iframe src, so the journey can identify what is embedding it. This happens once per attach, against the current (or first-assigned) src: if you later repoint the iframe yourself, call attach(iframe) again. Don't strip these parameters.

Lifecycle

attach(iframe) — called for you by the constructor — binds the host to an iframe and starts listening; you can call it again to rebind (pending state is preserved). Call detach() when you're done: the SDK installs a window message listener that otherwise keeps the host instance (and its message buffers) alive for the lifetime of the page.

License

MIT © GBG Group plc