Skip to content

Messages Reference

The CFC SDK uses a typed postMessage protocol for communication between the CFC iframe and the host application. All messages extend BaseMessage:

typescript
interface BaseMessage {
	type: string;
	messageId: string; // Auto-generated UUID
}

TIP

The SDK handles all these messages automatically. You don't need to listen for them manually — just provide callbacks in the CfcClientConfig. This page is a reference for understanding the protocol.

CFC to Host Messages

These messages are sent from the CFC iframe to the host application.

LOADED

Emitted when CFC has finished loading and is ready for interaction. The SDK automatically sends DIMENSIONS_CHANGED in response and calls onLoaded.

typescript
interface LoadedMessage extends BaseMessage {
	type: "LOADED";
}

Emitted when CFC navigates to a new page internally. The SDK calls onNavigated.

typescript
interface NavigatedToTargetMessage extends BaseMessage {
	type: "NAVIGATED_TO_TARGET";
	target: string;
	targetAction?: string;
}
FieldTypeDescription
targetstringThe navigation target path (e.g., '/view-payments')
targetActionstring | undefinedOptional action (e.g., 'schedulePaymentSuccess')

CONTENT_SIZE_CHANGE

Emitted when CFC content dimensions change. The SDK automatically resizes the iframe.

typescript
interface ContentSizeChangeMessage extends BaseMessage {
	type: "CONTENT_SIZE_CHANGE";
	height: number;
	width?: number;
}
FieldTypeDescription
heightnumberContent height in pixels
widthnumber | undefinedContent width in pixels (optional)

SCROLL_TO

Emitted when CFC requests the host to scroll. The SDK handles this automatically.

typescript
interface ScrollToMessage extends BaseMessage {
	type: "SCROLL_TO";
	relativeScrollX?: number;
	relativeScrollY?: number;
	preventScroll?: boolean;
}
FieldTypeDescription
relativeScrollXnumber | undefinedHorizontal scroll offset relative to iframe
relativeScrollYnumber | undefinedVertical scroll offset relative to iframe
preventScrollboolean | undefinedWhen true, lock host scrolling (e.g., modal open)

EXIT_REQUESTED

Emitted when the user wants to leave the CFC experience. Calls onExitRequested.

typescript
interface ExitRequestedMessage extends BaseMessage {
	type: "EXIT_REQUESTED";
	originator: string;
}
FieldTypeDescription
originatorstringIdentifier for what triggered the exit

AUTHENTICATION_ERROR

Emitted when CFC encounters an authentication problem. Calls onAuthenticationError.

typescript
interface AuthenticationErrorMessage extends BaseMessage {
	type: "AUTHENTICATION_ERROR";
	reason: AuthErrorReason;
	message: string;
}
FieldTypeDescription
reasonAuthErrorReasonError reason code (see Error Handling)
messagestringHuman-readable error description

SESSION_EXPIRED

Emitted when the CFC session has expired. Calls onSessionExpired.

typescript
interface SessionExpiredMessage extends BaseMessage {
	type: "SESSION_EXPIRED";
}

USER_ACTIVE_PING

Emitted periodically when the user is actively interacting with CFC. Calls onUserActivePing.

typescript
interface UserActivePingMessage extends BaseMessage {
	type: "USER_ACTIVE_PING";
}

SUBSCRIPTION_UPGRADE_REQUEST

Emitted when a CFC feature requires a subscription upgrade. Calls onUpgradeRequest.

typescript
interface SubscriptionUpgradeRequestMessage extends BaseMessage {
	type: "SUBSCRIPTION_UPGRADE_REQUEST";
	featureName: string;
	returnUrl: string;
}
FieldTypeDescription
featureNamestringThe feature that requires an upgrade
returnUrlstringURL to return to after the upgrade flow

See Subscription Management for the full flow.


Host to CFC Messages

These messages are sent from the host application to the CFC iframe. The SDK sends most of these automatically.

Request CFC to navigate to a specific target. Use client.navigateTo():

typescript
import { NavigationTarget } from "@melio-eng/cfc-sdk";

client.navigateTo(NavigationTarget.VIEW_PAYMENTS);
client.navigateTo(NavigationTarget.viewBill("bill-123"));
typescript
interface NavigateRequestMessage extends BaseMessage {
	type: "NAVIGATE_REQUEST";
	target: string;
}

USER_SCROLL

Sent automatically by the SDK on every host scroll event.

typescript
interface UserScrollMessage extends BaseMessage {
	type: "USER_SCROLL";
	scrollX: number;
	scrollY: number;
}

DIMENSIONS_CHANGED

Sent automatically by the SDK on load, resize, and visual viewport change.

typescript
interface DimensionsChangedMessage extends BaseMessage {
	type: "DIMENSIONS_CHANGED";
	windowHeight: number;
	windowWidth: number;
	elementDistanceFromTop: number;
	elementDistanceFromLeft: number;
	visualViewportHeight?: number;
	visualViewportWidth?: number;
	minimumContentHeight?: number;
}
FieldTypeDescription
windowHeightnumberwindow.innerHeight
windowWidthnumberwindow.innerWidth
elementDistanceFromTopnumberIframe top offset from document top
elementDistanceFromLeftnumberIframe left offset from document left
visualViewportHeightnumber | undefinedVisual viewport height (accounts for mobile keyboard)
visualViewportWidthnumber | undefinedVisual viewport width
minimumContentHeightnumber | undefinedOptional minimum height hint

SUBSCRIPTION_UPGRADE_FINISHED

Inform CFC that a subscription upgrade flow has completed. Use client.sendSubscriptionUpgradeFinished():

typescript
client.sendSubscriptionUpgradeFinished(true); // upgraded
client.sendSubscriptionUpgradeFinished(false); // cancelled
typescript
interface SubscriptionUpgradeFinishedMessage extends BaseMessage {
	type: "SUBSCRIPTION_UPGRADE_FINISHED";
	wasUpgraded: boolean;
}

Union Types

The SDK exports discriminated union types for type-safe message handling:

typescript
// All CFC -> Host message types
type CfcMessage = NavigatedToTargetMessage | LoadedMessage | ContentSizeChangeMessage | ScrollToMessage | ExitRequestedMessage | AuthenticationErrorMessage | SessionExpiredMessage | UserActivePingMessage | SubscriptionUpgradeRequestMessage;

// All Host -> CFC message types
type HostMessage = NavigateRequestMessage | UserScrollMessage | DimensionsChangedMessage | SubscriptionUpgradeFinishedMessage;

MessageType Constants

Use MessageType for autocomplete-friendly access to all message type strings. For more precise typing, use IncomingMessageType (CFC to Host) or OutgoingMessageType (Host to CFC):

typescript
import { MessageType, IncomingMessageType, OutgoingMessageType } from "@melio-eng/cfc-sdk";

// All message types
MessageType.LOADED; // 'LOADED'
MessageType.NAVIGATE_REQUEST; // 'NAVIGATE_REQUEST'

// Only CFC -> Host messages
IncomingMessageType.LOADED; // 'LOADED'
IncomingMessageType.CONTENT_SIZE_CHANGE; // 'CONTENT_SIZE_CHANGE'
IncomingMessageType.NAVIGATED_TO_TARGET; // 'NAVIGATED_TO_TARGET'

// Only Host -> CFC messages
OutgoingMessageType.NAVIGATE_REQUEST; // 'NAVIGATE_REQUEST'
OutgoingMessageType.DIMENSIONS_CHANGED; // 'DIMENSIONS_CHANGED'