Configure Your Org for React Development
Integrate Your React App with the Headless 360 Platform
Style Your React Apps
Integrate Agentforce Conversation Client
Get App Identity
Manage the Host UI
Localize Your App
Use Skills for Data Access
Use the View SDK to interact with the host’s UI layer from a UI bundle. The host is the application that embeds and runs your UI bundle, such as a parent Lightning web component that embeds your app or an agent host. The View SDK is how your app coordinates with that host.
With the View SDK, you can display alerts, toasts, and modals, read and subscribe to host UI state, For example, you can also get the current theme, mark unsaved changes, exchange events with the host, and more.
Create an instance with createViewSDK(), then call its methods under the returned SDK.
1import { createViewSDK } from "@salesforce/platform-sdk";
2
3const viewSDK = await createViewSDK();
4
5await viewSDK.displayToast?.({
6 message: "Operation completed successfully",
7 level: "success",
8});Every method is optional and resolves only on surfaces that support it. On web apps without an embedding host, createViewSDK() returns an empty SDK and doesn’t return an error. Use optional chaining (viewSDK.displayToast?.(...)) to account for the absence of a host UI.
Creates and initializes a View SDK instance.
1async function createViewSDK(options?: ViewSDKOptions): Promise<ViewSDK>;| Parameter | Type | Description |
|---|---|---|
options? | ViewSDKOptions | Optional configuration. Extends SDKOptions with a surface override. |
1Promise<ViewSDK>createViewSDK() never rejects on an unusable surface. Every surface degrades to an empty SDK so that the embedding host always renders.
To reuse one View SDK instance across your app, use getViewSDK(). It creates the instance on the first call and returns the same cached instance on later calls. Only the first call’s options take effect.
1import { getViewSDK } from "@salesforce/platform-sdk";
2
3const viewSDK = await getViewSDK();Where an async call isn’t available, use getViewSDKSync(). It returns the resolved instance if getViewSDK() has already completed, or null if the instance isn’t ready.
1import { getViewSDKSync } from "@salesforce/platform-sdk";
2
3const viewSDK = getViewSDKSync();
4if (viewSDK) {
5 const theme = viewSDK.getTheme?.();
6}The API returned by createViewSDK(). All methods are optional and are absent on a surface that doesn’t support them. The View SDK is also a DOM EventTarget, so it optionally exposes addEventListener, removeEventListener, and dispatchEvent.
| Method | Description |
|---|---|
displayAlert | Displays a modal alert that requires user acknowledgment. Use it for important messages. |
displayToast | Displays a non-blocking toast that auto-dismisses. Use it for confirmations and status updates. |
displayModal | Displays a modal dialog with custom HTML loaded from a UI resource. |
navigateTo | Navigates to a URL in the host environment. |
markDirtyState | Notifies the host that the app has unsaved changes. |
clearDirtyState | Notifies the host that all changes are saved. |
getUiState | Returns the current host UI state snapshot and a subscribe function for future changes. |
getTheme | Returns the current theme (light or dark), or null if the host doesn’t provide theme information. |
resize | Requests the host to resize the app container. |
Displays a modal alert in the host environment. Alerts block interaction until the user acknowledges them.
1displayAlert?(options: AlertOptions): Promise<void>;AlertOptions has a required message string and an optional level of "info", "success", "warning", or "error". The level defaults to "info".
1await viewSDK.displayAlert?.({
2 message: "Save your work before continuing.",
3 level: "warning",
4});Displays a non-blocking toast notification that dismisses automatically.
1displayToast?(options: ToastOptions): Promise<void>;ToastOptions has the same shape as AlertOptions: a required message and an optional level.
1await viewSDK.displayToast?.({
2 message: "File uploaded successfully.",
3 level: "success",
4});Displays a modal dialog with custom HTML loaded from a UI resource.
1displayModal?(options: ModalOptions): Promise<void>;| Parameter | Type | Description |
|---|---|---|
componentReference | string | URI of the HTML template to load, in the format ui://widget/[name].html. |
params | Record<string, unknown> | Optional. Parameters passed to the modal template, accessible through the host’s API. |
1await viewSDK.displayModal?.({
2 componentReference: "ui://widget/settings.html",
3 params: { theme: "dark" },
4});Navigates to a URL in the host environment. The exact behavior depends on the surface, such as a full-page navigation or an iframe navigation.
1navigateTo?(url: string): Promise<void>;1await viewSDK.navigateTo?.("/dashboard");Notifies the host that the app has unsaved changes. When the state is dirty, the host can show an indicator and warn the user before they navigate away. Pass an optional label to track multiple concurrent dirty regions.
1markDirtyState?(label?: string): Promise<void>;1form.addEventListener("input", () => viewSDK.markDirtyState?.("PrimaryForm"));Notifies the host that the app’s unsaved changes are resolved. Pass the same label that you passed to markDirtyState() to clear that dirty region.
1clearDirtyState?(label?: string): Promise<void>;1async function saveForm(data) {
2 await api.save(data);
3 await viewSDK.clearDirtyState?.("PrimaryForm");
4}Returns the current host UI state snapshot and a subscribe function for future changes. The snapshot has props, the host-configurable inputs such as theme, locale, and mode, and styles, the CSS custom properties and attributes the host mirrors onto the surface. Call subscribe with a handler to be notified on each later host push. subscribe returns an unsubscribe function that detaches that one handler.
1getUiState?<State extends UiState = UiState>(): {
2 state: State;
3 subscribe: (handler: (state: State) => void) => () => void;
4};1const { state, subscribe } = viewSDK.getUiState?.() ?? {
2 state: { props: {}, styles: {} },
3 subscribe: () => () => {},
4};
5
6applyProps(state.props);
7const unsubscribe = subscribe((next) => applyProps(next.props));
8// Call unsubscribe() when you no longer need updates.To type the snapshot for a known host contract, pass a type that extends UiState as the type parameter. State is erased at runtime, so pin only what the host guarantees.
Returns the current theme, or null if the host doesn’t provide theme information. getTheme() is the synchronous sibling of the theme data in getUiState().
1getTheme?(): Theme | null;1const theme = viewSDK.getTheme?.();
2if (theme) {
3 document.body.classList.toggle("dark", theme.mode === "dark");
4}Requests the host to resize the app container. Pass a width and a height as CSS length strings, or "auto" to size to the content.
1resize?(width: string, height: string): Promise<void>;1await viewSDK.resize?.("800px", "600px");
2await viewSDK.resize?.("auto", "auto");The View SDK is a DOM EventTarget. On surfaces backed by a host bridge, dispatchEvent notifies local listeners and forwards the event to the host, and events the host pushes are re-dispatched onto the SDK so addEventListener hears them. The result is one unified stream of host-pushed and same-document events.
The EventTarget members are optional, because a surface without an event bus is a bare SDK. Feature-detect before you use them.
1viewSDK.addEventListener?.("user-action", (e) => {
2 console.log("received:", (e as CustomEvent).detail);
3});
4
5viewSDK.dispatchEvent?.(new CustomEvent("user-action", { detail: { action: "click" } }));This example reads the theme inside an effect and subscribes to later changes. Guard the async result against a component that unmounts before the promise settles, and detach the subscription on cleanup.
1import { useEffect, useState } from "react";
2import { createViewSDK, type ThemeMode } from "@salesforce/platform-sdk";
3
4function useHostTheme(): ThemeMode {
5 const [mode, setMode] = useState<ThemeMode>("light");
6
7 useEffect(() => {
8 let cancelled = false;
9 let unsubscribe: (() => void) | undefined;
10
11 createViewSDK().then((viewSDK) => {
12 if (cancelled) return;
13
14 const initial = viewSDK.getTheme?.();
15 if (initial) setMode(initial.mode);
16
17 const uiState = viewSDK.getUiState?.();
18 unsubscribe = uiState?.subscribe((next) => {
19 const themeMode = next.props.theme;
20 if (themeMode === "light" || themeMode === "dark") setMode(themeMode);
21 });
22 });
23
24 return () => {
25 cancelled = true;
26 unsubscribe?.();
27 };
28 }, []);
29
30 return mode;
31}