Protocol Reference
All envelopes, RPC methods, events, and error codes.
Constants
NAMESPACE = "__riftix_bridge" // envelope tag
PROTOCOL_VERSION = 1
DEFAULT_RPC_TIMEOUT_MS = 10_000 // 10s
DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000 // 10s
DEFAULT_HELLO_RETRY_INTERVAL_MS = 100 // 100msEnvelopes
All envelopes carry __riftix_bridge: "__riftix_bridge" as a discriminator. Use isEnvelope(value) from @riftix/console-bridge-types to narrow unknown postMessage data.
hello (client → host)
{
__riftix_bridge: "__riftix_bridge";
kind: "hello";
protocolVersion: 1;
capabilities: readonly string[];
}Sent by the client on load, retried every DEFAULT_HELLO_RETRY_INTERVAL_MS until ready is received or the handshake times out.
ready (host → client)
{
__riftix_bridge: "__riftix_bridge";
kind: "ready";
protocolVersion: 1;
capabilities: readonly string[];
context: HostContext;
}Carries the initial context snapshot so the client can paint before the first context:changed event.
req (client → host)
{
__riftix_bridge: "__riftix_bridge";
kind: "req";
id: string; // crypto.randomUUID()
method: BridgeMethodName;
payload: BridgeMethodRequest<method>;
}res (host → client)
// Success
{
__riftix_bridge: "__riftix_bridge";
kind: "res";
id: string;
ok: true;
data: BridgeMethodResponse<method>;
}
// Failure
{
__riftix_bridge: "__riftix_bridge";
kind: "res";
id: string;
ok: false;
error: BridgeErrorPayload;
}event (host → client)
{
__riftix_bridge: "__riftix_bridge";
kind: "event";
event: BridgeEventName;
payload: BridgeEventPayload<event>;
}RPC Methods
navigation.navigate
Navigate the host shell to a route.
// Request
{ to: string; replace?: boolean }
// Response
voidnavigation.setTitle
Update the page title displayed in the host navbar.
// Request
{ title: string; subtitle?: string }
// Response
voidnavigation.setBreadcrumbs
Replace the breadcrumb trail for this product in the host navbar. An empty array clears the breadcrumbs.
// Request
{ crumbs: ReadonlyArray<BridgeBreadcrumb> }
// Response
voidBridgeBreadcrumb:
{ label: string; href?: string }This RPC is handled automatically by the host — you do not need to register a handler for it. The built-in handler calls channel._applyClientBreadcrumbs(crumbs).
navigation.locationChanged
Report the iframe's current URL to the host. Sent automatically by the snippet on page load and on every subsequent URL change (pushState, replaceState, popstate). You do not call this manually — it is driven by setupLocationSync inside the snippet.
// Request
{ path: string } // pathname + search + hash, e.g. "/invoices/123?tab=summary"
// Response
voidThis RPC is handled automatically by the host — you do not need to register a handler for it. The built-in handler calls channel._applyClientLocation(payload.path), which stores the path and fires any onLocationChanged subscribers (e.g. ConsoleIframe's onLocation prop).
toast.show
Show a toast notification in the host shell.
// Request
{
message: string;
variant?: "info" | "success" | "warning" | "error";
durationMs?: number;
}
// Response
voidmodal.confirm
Open a confirmation dialog in the host shell and return the user's choice.
// Request
{
title: string;
body: string;
confirmLabel?: string;
cancelLabel?: string;
destructive?: boolean;
}
// Response
boolean // true = confirmed, false = cancelledEvents
context:changed
Fired when the host context changes. Carries the full new snapshot.
payload: HostContext
// { theme: "light" | "dark"; locale: string }authorization:changed
Fired when authorization changes, including immediately after handshake (may be null if no auth has been issued for this product yet).
payload: BridgeAuthorization | nullBridgeAuthorization:
{
clientId: string; // product ID
organizationId: string; // tenant / organization ID
token: string; // JWT or opaque bearer token
expiresAt: number; // Unix ms timestamp
}navigation:navigate
Sent by the host when it wants the running iframe to navigate to a specific path — for example when the user hits the browser back/forward buttons at the host level, or when the host URL is updated programmatically after the iframe is already running.
The snippet handles this automatically: it calls history.pushState or history.replaceState and then dispatches a synthetic popstate event so in-page routers (TanStack Router, React Router, etc.) pick up the change.
payload: {
path: string; // target path within the product, e.g. "/invoices/123"
replace?: boolean; // true → replaceState, false/absent → pushState
}Send from the host via channel.emit("navigation:navigate", { path, replace }) or host.broadcast("navigation:navigate", { path, replace }).
Error Codes
enum BridgeErrorCode {
HANDSHAKE_TIMEOUT // client: handshake not completed within 10s
PROTOCOL_VERSION_MISMATCH // host drops hello with wrong protocolVersion
METHOD_NOT_FOUND // host: no handler registered for method
INVALID_ORIGIN // host: message from unexpected origin
HANDLER_ERROR // host: registered handler threw
TIMEOUT // client: req timed out waiting for res
DISCONNECTED // channel disposed before res arrived
INVALID_ENVELOPE // malformed envelope shape
}BridgeError (thrown on the client for failed RPCs):
class BridgeError extends Error {
readonly code: BridgeErrorCode;
readonly details: unknown;
}