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+
Architecture
Section titled “Architecture”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 --> NavDesign principles
Section titled “Design principles”| 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. |
What replaced the window pattern
Section titled “What replaced the window pattern”Previously, MFEs read globals at import time:
window.SEGMENTIFY_API_INSTANCE.API.get(...)window.SEGMENTIFY_API_INSTANCE.environmentwindow.SEGMENTIFY_API_INSTANCE.hostBaseUrlThis 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() |
Bridge registry
Section titled “Bridge registry”When a host registers the bridge:
- The bridge is stored in
hostBridgeStore(module state in@segmentify/common). - It is published to
window.SEGMENTIFY_HOST_BRIDGEso federated remotes with separate@segmentify/commonbundles can discover it across module graphs. - A
segmentify:host-bridge-readycustom event fires so waiting MFEs resolvewaitForHostBridge()immediately.
MFEs call waitForHostBridge() — it resolves immediately if the bridge is already
registered, or waits for the ready event.
The three host adapters
Section titled “The three host adapters”| 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.
What CDP reads from the bridge
Section titled “What CDP reads from the bridge”- HTTP client —
cdpApiis built withcreateMfeApi({ useCdpApi: true })and resolves its base URL frombridge.resolveApiBaseUrl('cdp', { datacenter }). CDP addsX-Api-Version: 1.0automatically. - Account context —
BridgeHostDataProvidersubscribes to host data updates and exposesuseApiKey()/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).
HostBridgeV1 contract
Section titled “HostBridgeV1 contract”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;}How CDP bootstraps in each mode
Section titled “How CDP bootstraps in each mode”| 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.
Dashboard internal usage
Section titled “Dashboard internal usage”No changes are required for normal dashboard development. The shell automatically registers the bridge when the API module loads:
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.
Host data shape (minimum for API calls)
Section titled “Host data shape (minimum for API calls)”{ 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).
API quick reference
Section titled “API quick reference”Registry
Section titled “Registry”setHostBridge(bridge)/getHostBridge()/waitForHostBridge()registerSegmentifyHostApi(instance)— dashboard only
Host adapters
Section titled “Host adapters”createSegmentifyDashboardBridge(options)— internal (dashboard)createDirectConfigBridge(config)— partner Module Federation mountcreatePostMessageBridge(options)— iframe MFE sidebindPostMessageHost(iframe, payload, options)— iframe parent sideinitPostMessageEmbed(options)— MFE embed bootstrap (embed.html)
MFE runtime
Section titled “MFE runtime”createMfeApi(options)— HTTP client for MFE domain APIscreateEmbedApiClient(options)— partner Bearer-token clientgetHostEnvironment()— environment string (bridge-first, legacy fallback)BridgeHostDataProvider— React context from bridgenavigateHost(path)/getHostBaseUrl()— host navigation helperssetBreadcrumbOnHost()/hideBreadcrumbOnHost()— dashboard breadcrumb chrome
Security
Section titled “Security”isTrustedPostMessageEvent(event, source, origin)
See the full API reference for message types, mount signatures, and version history.