SDK Reference
SDK Packages
The CDX Extensibility SDK is split into three packages, all installed automatically via npm install.
Core SDK — @cdx-extensions/di-sdk
This is the main entry point. It is the platform-agnostic orchestration layer that your widget imports and uses directly. It detects the runtime environment and delegates every method call to the correct platform implementation.
How it works:
- It is a singleton (
PlatformSDK.getInstance()). The same object is returned regardless of how many timesgetInstanceis invoked. - All utility calls (
useUserContext,useBranding,getHttpClient) are delegated to the active platform — the harness locally, or the real platform implementation in production.
Usage in a widget:
import { PlatformSDK } from '@cdx-extensions/di-sdk';
const sdk = PlatformSDK.getInstance();
const { data: user } = sdk.useUserContext();
const { theme } = sdk.useBranding('branding-1');
const httpClient = sdk.getHttpClient();
Always import from @cdx-extensions/di-sdk. Do not import from di-sdk-web or di-sdk-mobile directly — the main SDK selects the correct implementation at runtime.
Platform Harness
The harness is the mock/harness implementation of the platform SDK for local development. It provides everything a widget needs to run locally without the real platform present.
- Web
- Mobile
Package: @cdx-extensions/di-sdk-web
What it provides locally:
- Mock user context data (from
mocks/userContext.json) - Mock API responses with simulated delays (from
mocks/apiResponses.json) - Mock branding/theme data (from
mocks/branding.json)- Locally, global-level branding is applied on the OLB regardless of changes at the widget level.
- On the OLB, global branding and theming are applied automatically.
- A mock HTTP client backed by
axios-mock-adapter
On the public npm registry, this package is the harness. On internal JFrog, the same package name resolves to the real OLB implementation. Your widget code works in both environments — only the registry determines which version is installed.
Package: @cdx-extensions/di-sdk-mobile
What it provides locally:
- Mock user context data (from
mocks/userContext.json) - Mock API responses with simulated delays (from
mocks/apiResponses.json) - Mock branding/theme data (from
mocks/branding-default.json, plus 5 named variants:branding-classic-blue.json,branding-purple-elegance.json,branding-ocean-blue.json,branding-forest-green.json,branding-crimson-red.json) - A mock HTTP client backed by
axios-mock-adapter
Type Definitions — @cdx-extensions/di-sdk-types
Shared TypeScript interfaces used across all SDK packages and your widget code. This package has no runtime logic — types only. The type definitions are identical across web and mobile.
Key types:
| Type | Description |
|---|---|
UserContext | Shape of data returned by useUserContext() |
Platform | Interface that both web and mobile platforms implement |
HttpClient | Interface for getHttpClient() — methods: get, post, put, patch, delete |
HttpResponse<T> | Wrapper around API responses: data, status, statusText, headers |
ExtensibilityConfig | Platform config: environment, apiBaseUrl, features, customSettings |
Response<T> | Wrapper returned by React hooks: data, isLoading, hasError, error |
Usage:
import { UserContext, HttpClient, ExtensibilityConfig } from '@cdx-extensions/di-sdk-types';
SDK Method Reference
useUserContext()
Returns the logged-in user's context — injected by the platform when embedded.
const sdk = PlatformSDK.getInstance();
const { data: user, isLoading, hasError } = sdk.useUserContext();
Shape of data (UserContext):
| Field | Type | Description |
|---|---|---|
guid | string | Platform-wide unique user identifier |
firstName | string | User's first name |
lastName | string | User's last name |
fullName | string | Full display name |
userName | string | Login username |
email | string | User email |
institutionUserId | string | Institution-specific user ID |
institutionUserRole | string | Role within the institution (e.g. user, admin) |
institutionUserType | string | Account tier (e.g. premium, retail) |
institutionId | string | The institution identifier |
- Web
- Mobile
Locally: Data is read from node_modules/@cdx-extensions/di-sdk-web/dist/mocks/userContext.json.
On the OLB: The real platform injects the actual logged-in user's data. The widget code does not change — only the source of data changes.
Locally: Data is read from node_modules/@cdx-extensions/di-sdk-mobile/dist/mocks/userContext.json. To test with different user attributes, edit this file.
In production: The real mobile banking platform injects the actual logged-in user's data. Your code does not change — only the source of data changes.
Example (from useWelcomeUser.ts):
import { useMemo } from 'react';
import { PlatformSDK } from '@cdx-extensions/di-sdk';
export function useWelcomeUser() {
const sdk = useMemo(() => PlatformSDK.getInstance(), []);
const userContextResult: any = sdk.useUserContext();
const data = userContextResult?.data;
const isLoading = Boolean(userContextResult?.isLoading);
const hasError = Boolean(userContextResult?.hasError ?? userContextResult?.error);
const userName = data?.fullName ?? 'NA';
const error = hasError ? 'Failed to fetch user data' : null;
return { userName, isLoading, error };
}
useBranding(brandingId?)
Returns branding tokens for styling your user interface. The return type differs by platform.
- Web
- Mobile
Returns a MUI theme object built from the platform's branding configuration. Pass it to MUI ThemeProvider to apply the host platform's visual style.
const { theme } = sdk.useBranding('branding-1');
return (
<ThemeProvider theme={theme}>
<YourComponent />
</ThemeProvider>
);
Locally: Theme is built from the mock branding JSON files under node_modules/@cdx-extensions/di-sdk-web/dist/mocks/. Five commonly used branding variants are included (branding-1 through branding-5).
On the OLB: The platform's real branding service provides the live theme for the institution. Global-level theming is applied automatically, so widget-level theming will be overridden on the OLB.
Returns a React Native–oriented theme (MobileBrandingTheme from @cdx-extensions/di-sdk-types), not the MUI theme object used on web.
import { PlatformSDK } from '@cdx-extensions/di-sdk';
import type { MobileBrandingTheme } from '@cdx-extensions/di-sdk-types';
const sdk = PlatformSDK.getInstance();
const { theme } = sdk.useBranding();
const t = theme as MobileBrandingTheme | null;
const primary = t?.colors?.primary?.main ?? '#1976d2';
Optional identifier (supported where the platform exposes multiple brand packs). The mobile sandbox ships with named variants such as branding-classic-blue, branding-purple-elegance, etc.:
const { theme } = sdk.useBranding('branding-classic-blue');
Parameters
| Parameter | Type | Description |
|---|---|---|
brandingId | string (optional) | Selects a specific branding variant when the host or harness supports multiple packs. |
Return value
| Field | Type | Description |
|---|---|---|
theme | MobileBrandingTheme | Semantic token groups: colors, fonts, fontSizes, and optional components. Use optional chaining and provide local fallbacks for any missing nested field. |
MobileBrandingTheme structure:
| Group | Examples |
|---|---|
colors | primary, secondary, error, warning, success, info, text, background |
fonts | heading, body |
fontSizes | xs, sm, md, lg, xl, optional 2xl, 3xl |
components | Optional component-level tokens (Text, Box, Button, etc.) |
useBranding is a React hook. Call it from function components or custom hooks only. It uses the same rules as useState or useContext.
The optional brandingId argument is primarily relevant where the sandbox supports switching between named brand packs. On mobile, the harness does not switch the active theme by argument — the mock is driven by the sandbox Settings / branding context. On the production host, brandingId is unused; rely on the host's current branding instead.
Locally: The mobile harness resolves branding from mock data under node_modules/@cdx-extensions/di-sdk-mobile/dist/mocks/. The default fallback is branding-default.json. The sandbox BrandingProvider supports five switchable named variants. Design your feature or widget so it renders with sensible defaults when tokens are absent.
In production: The platform supplies the institution's live branding. Do not hardcode institution-specific colors as the only source of truth. Use SDK tokens where available, so branding changes propagate automatically.
The mobile harness (@cdx-extensions/di-sdk-mobile) also exports granular theming hooks for sandbox development: useColorsTheme(), useFontSizeTheme(), useBoxTheme(), useButtonTheme(), useTextFontTheme(), useHeadingFontTheme(), and others. These mirror the host app's internal theming hooks and are useful when building sandbox screens that need direct access to specific token groups. For feature or widget code that ships to production, use sdk.useBranding() from @cdx-extensions/di-sdk instead.
Example — applying branding defensively:
import React, { useMemo } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { PlatformSDK } from '@cdx-extensions/di-sdk';
import type { MobileBrandingTheme } from '@cdx-extensions/di-sdk-types';
export function BrandedCard() {
const sdk = useMemo(() => PlatformSDK.getInstance(), []);
const { theme } = sdk.useBranding();
const t = theme as MobileBrandingTheme | null;
const backgroundColor = t?.colors?.background?.default ?? '#FFFFFF';
const textColor = t?.colors?.text?.primary ?? '#111827';
const fontFamily = t?.fonts?.body ?? undefined;
return (
<View style={[styles.card, { backgroundColor }]}>
<Text style={[styles.label, { color: textColor, fontFamily }]}>
Branded content
</Text>
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 16, borderRadius: 8 },
label: { fontSize: 16 },
});
getHttpClient()
Returns an HTTP client for making API calls. This method has the most significant difference between local and production environments.
Always use sdk.getHttpClient() for all API calls in your widget. Never use raw fetch() or import Axios directly. The HTTP client handles auth, mocking, and platform security automatically.
Behavior comparison
- Web
- Mobile
| Local (harness) | On OLB (prod) | |
|---|---|---|
| Returns | Axios instance backed by axios-mock-adapter | Real Axios instance managed by the OLB platform |
| Auth | No real auth; optionally uses a static access_token string | Full OIDC flow — token is injected automatically by the platform |
| API calls | Intercepted and served from apiResponses.json | Real HTTP calls to your third-party API endpoints |
| Requires whitelisting | No | Yes — third-party domains must be manually whitelisted |
| Local (harness) | In Production | |
|---|---|---|
| Returns | Axios instance backed by axios-mock-adapter | Real Axios instance managed by the mobile banking platform |
| Auth | No real auth; optionally uses a static access_token string | Full OIDC flow — token is injected automatically by the platform |
| API calls | Intercepted and served from apiResponses.json | Real HTTP calls to configured external API endpoints |
| Requires whitelisting | No | Yes — configured external API endpoint domains must be whitelisted |
Local: mock mode (default)
By default, all API calls are intercepted and served from mock data.
- Web
- Mobile
File: node_modules/@cdx-extensions/di-sdk-web/dist/httpClient.js
The key flag:
const isMock = true;
When isMock = true:
- Every
httpClient.get(url)/post/put/patch/deleteis intercepted. - The response comes from
mocks/apiResponses.jsonwith a simulated delay (default: 500ms–2000ms). - No real network call is made.
- Responses are logged in the browser console with prefix
[WEB-HARNESS-HTTP].
To add a new mock endpoint locally, add an entry to apiResponses.json:
{
"url": "/api/your-endpoint",
"method": "GET",
"status": 200,
"delay": { "min": 300, "max": 800 },
"data": {
"yourField": "yourValue"
}
}
File: node_modules/@cdx-extensions/di-sdk-mobile/dist/httpClient.js
The key flag:
const isMock = true;
Find this variable near the top of the file. When isMock = true:
- Every
httpClient.get(url)/post/put/patch/deleteis intercepted. - The response comes from
mocks/apiResponses.jsonwith a simulated delay (default: 500ms–2000ms). - No real network call is made.
- Responses are logged in the device console / Metro terminal with prefix
[MOBILE-HARNESS-HTTP].
To add a new mock endpoint locally, add an entry to the responses array in node_modules/@cdx-extensions/di-sdk-mobile/dist/mocks/apiResponses.json:
{
"url": "https://api.example.com/api/your-endpoint",
"method": "GET",
"status": 200,
"delay": { "min": 300, "max": 800 },
"data": {
"yourField": "yourValue"
}
}
The mock adapter matches requests by exact full URL. The URL in apiResponses.json must match the full URL your code builds from config.baseUrl + config.apiPath. If you use a relative path like /api/your-endpoint but your code calls https://api.example.com/api/your-endpoint, the mock will not match.
The file also has a defaultDelay setting at the top that applies when individual responses omit the delay field:
{
"defaultDelay": {
"min": 500,
"max": 2000
},
"responses": [ ... ]
}
Local: real HTTP mode
To call a real external URL during local development (e.g. a sandbox API):
- Web
- Mobile
-
Open
node_modules/@cdx-extensions/di-sdk-web/dist/httpClient.jsChange line 8 from:
const isMock = true;to:
const isMock = false; -
Optionally set your access token on line 10:
const access_token = 'your-real-token-here'; -
Update the API base URL in your widget's environment file:
widgets/web/<your-widget>/src/environments/environment.ts -
Set
apiUrlto your real backend base URL.
When isMock = false, getHttpClient() returns a real Axios instance with a Bearer authorization header injected on every request.
If you need to disable Bearer token authentication, remove the following line from getHttpClient():
request.headers['Authorization'] = `Bearer ${access_token}`;
File location: node_modules/@cdx-extensions/di-sdk-web/dist/httpClient.js
-
Open
node_modules/@cdx-extensions/di-sdk-mobile/dist/httpClient.jsChange line 8 from:
const isMock = true;to:
const isMock = false; -
Optionally set your access token on line 10:
const access_token = 'your-real-token-here'; -
Update the API base URL in your
config.ts:// src/config.ts
export const config = {
baseUrl: 'https://your-real-api-server.com',
apiPath: '/your-endpoint',
};
Changes to node_modules/ are not committed to source control and will be overwritten by npm install. This is only for local testing sessions.
API configuration
A common pattern for managing API endpoints is a config.ts file. For a working example, see the investment-portfolio reference widget.
export const config = {
baseUrl: 'https://real-api-server.com',
apiPath: '/endpoint',
};
Making API calls
Use the HTTP client from the SDK to make requests:
import { useCallback, useMemo } from 'react';
import { PlatformSDK } from '@cdx-extensions/di-sdk';
import { config } from '../config';
export function usePortfolioData() {
const sdk = useMemo(() => PlatformSDK.getInstance(), []);
const fetchData = useCallback(async () => {
const client = sdk.getHttpClient();
const url = `${config.baseUrl}${config.apiPath}`;
const response = await client.get(url);
return response.data;
}, [sdk]);
// ... state management and error handling
}
The HttpClient interface provides the following methods:
| Method | Signature |
|---|---|
get | get<T>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>> |
post | post<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResponse<T>> |
put | put<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResponse<T>> |
patch | patch<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResponse<T>> |
delete | delete<T>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>> |
Next Steps
- Web
- Mobile
- Platform Capabilities (Local) — How each SDK method maps to mock data locally
- Widget Integration — Module Federation, registration, and deployment
- Platform Capabilities (Local) — How each SDK method maps to mock data locally
- Host App Integration — Repository structure and submission process