Skip to content

Module Federation mount

For hosts that can load the CDP remote entry and render React, the ./mount export gives deeper UI integration than an iframe (no cross-document boundary). The CDP remote exposes three entry points:

Export Description
./App React app for the Segmentify dashboard (default).
./mount mount(container, options) for partner SPAs.
./embed Auto-bootstrap postMessage iframe entry.
Field Value
Federation name cdp
Host import alias cdpApp
Remote entry https://cdp.segmentify.com/assets/remoteEntry.js
Local remote entry http://localhost:5001/assets/remoteEntry.js

Align these with the versions CDP builds against (from vite.config.ts):

federation({
remotes: {
cdpApp: "https://cdp.segmentify.com/assets/remoteEntry.js",
},
shared: ["react", "react-dom", "react-intl", "@tanstack/react-query", "react-hook-form"],
});
import { mount } from "cdpApp/mount";
import { createEmbedApiClient } from "@segmentify/common";
const { unmount, updateHostData, bridge } = await mount(
document.getElementById("segmentify-root")!,
{
basename: "/partner/segmentify/cdp",
host: {
environment: "production",
hostBaseUrl: "https://sauron.segmentify.com",
cdpBaseUrl: "https://api.segmentify.com",
cdpApi: createEmbedApiClient({
baseURL: "https://api.segmentify.com",
getAuthToken: () => getPartnerToken(),
defaultHeaders: {
"X-Switch-User": "user@example.com",
"X-Switch-Region": "ALL",
"X-Api-Version": "1.0",
},
}),
hostData: accountContext,
onNavigate: (path) => partnerRouter.push(path),
},
}
);
// Later
updateHostData(newAccountContext);
unmount();

mount returns a handle:

type CdpMountHandle = {
unmount: () => void;
bridge: DirectHostBridge;
updateHostData: (data: HostData) => void;
};

If you already have an axios-like client with auth, pass it as api / cdpApi instead of createEmbedApiClient. It must implement the HttpClient interface:

interface HttpClient {
get<T>(url: string, config?: HttpRequestConfig): Promise<T>;
post<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<T>;
put<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<T>;
patch?<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<T>;
delete?<T>(url: string, config?: HttpRequestConfig): Promise<T>;
extend?(options: { baseURL?: string; headers?: Record<string, string> }): HttpClient;
}

CDP renders inside a container with id="cdp-fr-app" and sets data-cdp-fr-app on <body> for portals/modals. Do not strip this wrapper markup — CDP’s scoped styles depend on it.

See the Angular integration guide for calling mount from an Angular host.