Skip to content

Host bridge overview

CDP never reads the host window directly. Instead, the host registers a HostBridgeV1 implementation with @segmentify/common, and CDP consumes it for HTTP, account context, and navigation. This keeps the contract versioned and lets the same MFE run in the Segmentify dashboard, an iframe, or a Module Federation host.

Package: @segmentify/common v0.0.15+

flowchart TD
subgraph host [Host application]
direction TB
A[Dashboard: registerSegmentifyHostApi]
B[iframe parent: bindPostMessageHost]
C[Federation host: createDirectConfigBridge]
end
Store[hostBridgeStore in @segmentify/common]
subgraph mfe [CDP micro frontend]
Api[createMfeApi cdpApi]
Data[BridgeHostDataProvider]
Nav[navigateHost / router sync]
end
A --> Store
B --> Store
C --> Store
Store --> Api
Store --> Data
Store --> Nav
Principle Implementation
Host owns HTTP Dashboard keeps its axios + interceptors; partners pass a token or inject a client.
MFE never reads window createMfeApi() waits for the bridge via waitForHostBridge().
Versioned contract HostBridgeV1 with version: '1'.
Multiple adapters Dashboard, direct config (mount), postMessage (iframe).
Backward compatible Dashboard still sets window.SEGMENTIFY_API_INSTANCE for legacy code paths.

Previously, MFEs read globals at import time:

window.SEGMENTIFY_API_INSTANCE.API.get(...)
window.SEGMENTIFY_API_INSTANCE.environment
window.SEGMENTIFY_API_INSTANCE.hostBaseUrl

This broke in Module Federation (duplicate bundles), iframe embeds, and partner integrations. The bridge replaces each concern:

Concern Old (window) New (bridge)
HTTP clients window.SEGMENTIFY_API_INSTANCE.API createMfeApi() → bridge.api / bridge.cdpApi
Environment window.SEGMENTIFY_API_INSTANCE.environment getHostEnvironment() (bridge-first)
Base URL window.SEGMENTIFY_API_INSTANCE.hostBaseUrl getHostBaseUrl() (bridge-first)
Account context Service worker listener / HostDataProvider BridgeHostDataProvider → subscribeHostData()
Navigation CustomEvent('NAVIGATE_TO_HOST_APP') navigateHost() → bridge.navigate()
Breadcrumbs CustomEvent('SET_BREADCRUMB') setBreadcrumbOnHost() → bridge.setBreadcrumb()

When a host registers the bridge:

  1. The bridge is stored in hostBridgeStore (module state in @segmentify/common).
  2. It is published to window.SEGMENTIFY_HOST_BRIDGE so federated remotes with separate @segmentify/common bundles can discover it across module graphs.
  3. A segmentify:host-bridge-ready custom event fires so waiting MFEs resolve waitForHostBridge() immediately.

MFEs call waitForHostBridge() — it resolves immediately if the bridge is already registered, or waits for the ready event.

Adapter Registered by Used for
registerSegmentifyHostApi() Segmentify dashboard Internal host shell
bindPostMessageHost(iframe, payload, options) iframe parent iframe embed
createDirectConfigBridge(config) React host code Module Federation mount

On the MFE side, iframe embeds use initPostMessageEmbed() (which internally calls createPostMessageBridge()) to wait for the parent’s SEGMENTIFY_HOST_INIT message before rendering the app.

  • HTTP client — cdpApi is built with createMfeApi({ useCdpApi: true }) and resolves its base URL from bridge.resolveApiBaseUrl('cdp', { datacenter }). CDP adds X-Api-Version: 1.0 automatically.
  • Account context — BridgeHostDataProvider subscribes to host data updates and exposes useApiKey() / useHostData() to the app.
  • Navigation — in dashboard mode the router syncs with the host URL; in embed mode navigation requests are forwarded to the parent (onNavigate).
interface HostBridgeV1 {
readonly version: "1";
readonly environment: HostEnvironment;
readonly hostBaseUrl: string;
readonly api: HttpClient;
readonly cdpApi?: HttpClient;
getHostData(): HostData;
subscribeHostData(listener: (data: HostData) => void): () => void;
navigate(path: string): void;
setBreadcrumb?(breadcrumb: BreadcrumbPayload | null): void;
getAuthToken(): string | null;
resolveApiBaseUrl(service: "host" | "cdp" | "reports", options?): string;
setCdpApiBaseUrl?(baseURL: string): void;
}
Mode Host registers via CDP entry point integrationMode
Dashboard registerSegmentifyHostApi() Federation ./App "dashboard"
iframe bindPostMessageHost() (parent) embed.html → initPostMessageEmbed() "embed"
Federation createDirectConfigBridge() in mount() ./mount export "embed"

In embed mode, host router sync is disabled (useHostRouterSync(router, false)). CDP renders under an empty basename and requests parent navigation via onNavigate.

No changes are required for normal dashboard development. The shell automatically registers the bridge when the API module loads:

dashboard/src/new_design/api/index.js
import { registerSegmentifyHostApi } from "@segmentify/common";
registerSegmentifyHostApi({
environment: getCurrentEnvironment(),
hostBaseUrl: baseUrlForEnvironment(),
cdpBaseUrl: resolveCdpApiBaseUrl(),
API,
CDP_API,
resolveCdpApiBaseUrl,
setCdpApiBaseUrl,
});

The dashboard loads CDP via federation (cdpApp/App) at base path /customer-data-platform.

{
user?: {
user?: {
account?: {
apiKey?: string;
dataCenter?: "eq" | "gc" | string;
mainCurrency?: { code?: string; symbol?: string };
};
lang?: string;
privileges?: string[];
};
};
switchedUser?: { /* optional multi-account */ };
switchRegion?: { selectedRegion?: string };
}

The dataCenter field matters in production: it selects the CDP API host (eq → api-eq, gc → api-gcp).

  • setHostBridge(bridge) / getHostBridge() / waitForHostBridge()
  • registerSegmentifyHostApi(instance) — dashboard only
  • createSegmentifyDashboardBridge(options) — internal (dashboard)
  • createDirectConfigBridge(config) — partner Module Federation mount
  • createPostMessageBridge(options) — iframe MFE side
  • bindPostMessageHost(iframe, payload, options) — iframe parent side
  • initPostMessageEmbed(options) — MFE embed bootstrap (embed.html)
  • createMfeApi(options) — HTTP client for MFE domain APIs
  • createEmbedApiClient(options) — partner Bearer-token client
  • getHostEnvironment() — environment string (bridge-first, legacy fallback)
  • BridgeHostDataProvider — React context from bridge
  • navigateHost(path) / getHostBaseUrl() — host navigation helpers
  • setBreadcrumbOnHost() / hideBreadcrumbOnHost() — dashboard breadcrumb chrome
  • isTrustedPostMessageEvent(event, source, origin)

See the full API reference for message types, mount signatures, and version history.