Get Started with UI Embedding

Embed an existing external web app directly in Salesforce so your users work in one place instead of switching to a separate tab or window. With UI Embedding, Salesforce hosts your app inside a secure, sandboxed iframe by using the lightning-ui-embedding base component. This guide sets up the shared foundation, then walks you through the two configuration paths so you can choose the one that fits your project.

UI Embedding was previously available as a Developer Preview. The Developer Preview used a different host element and setup flow. If you built against the preview, see Migrate from the Developer Preview API before you move to the generally available version.

Note

Prerequisites 

  • Your web app is hosted at an HTTPS URL that you control.
  • You have permission to create Lightning web components and edit Lightning pages or Experience Cloud sites in your Salesforce org.
  • Your Salesforce org is on a release where UI Embedding is generally available. You don’t need to set a specific API version on the lightning-ui-embedding component.
  • UI Embedding is available in Enterprise, Performance, Unlimited, Developer, and Partner Developer editions, in orgs hosted on Hyperforce where English is the default language.

Choose a Configuration Path 

You embed an app the same way in every case: you trust the app’s domain, add the lightning-ui-embedding component to a page, and point it at your app. What differs is how your app talks back to Salesforce. Pick the path that matches how much you want to depend on a Salesforce package.

PathUse whenHow the app communicates
With a Salesforce packageYou want the fastest setup and a supported, typed API.Your app imports the platform SDK, which manages the communication channel for you.
Without a Salesforce packageYou can’t or don’t want to add a Salesforce package to your app’s build, or you want full control of the communication layer.Your app implements the sf-embedding protocol directly over the channel Salesforce provides.

Both paths use the same host component and the same underlying protocol, so you can start with one and move to the other later without re-architecting the embedding.

Trust Your App's Domain 

This step is the same for both paths. Salesforce loads your app in an iframe, so you first tell Salesforce to trust your app’s origin. From Setup, add your app’s origin to your trusted URL settings for inline frames.

Use the exact origin that serves your app, including the scheme and any subdomain. An origin that doesn’t match the app’s real origin prevents the app from loading. The app’s origin must also differ from your Salesforce org’s origin. A same-origin src is rejected with a SAME_ORIGIN_SRC error, so host the app on a different origin.

Important

Add the Embedding Component 

This step is also the same for both paths. Create a Lightning web component that renders lightning-ui-embedding and points it at your app’s URL.

  1. In your Salesforce DX project, create a Lightning web component. This component is a thin wrapper around the embedding component.
  2. In the component’s template, add lightning-ui-embedding and set the required src attribute to your app’s URL.
1<!-- myEmbeddedApp.html -->
2<template>
3  <lightning-ui-embedding src="{appUrl}"></lightning-ui-embedding>
4</template>
1// myEmbeddedApp.js
2import { LightningElement } from "lwc";
3
4export default class MyEmbeddedApp extends LightningElement {
5  appUrl = "https://app.example.com";
6}

This code is a starting sketch. Replace https://app.example.com with your app’s URL. To give the embedded frame an accessible name, set the title attribute; if you don’t, the frame uses the default name Embedded widget.

Note

The src attribute is required, and Salesforce reads it when the component mounts. Because src binds the session to a specific app, don’t change it after the component renders. This is enforced: changing src (or sandbox) after mount fires an sf-embedding.component.error with the code SESSION_BINDING_MUTATED. To load a different URL, unmount and remount the component.

Then place your wrapper on a page like any other Lightning web component.

  1. Open Lightning App Builder for a Lightning page, or open your Experience Cloud site in Experience Builder.
  2. Drag your custom component onto the page.
  3. Save and activate the page.

Your embedded app now renders inside Salesforce. Next, choose a configuration path to connect your app to Salesforce.

Path 1: Configure With a Salesforce Package 

On this path, your app depends on the Salesforce platform SDK, which manages the communication channel for you. You get a supported, typed API for the lifecycle, UI state, resizing, and dirty-state features without writing any protocol code.

  1. Add the platform SDK to your app and import the UI Embedding entry point.
1import "@salesforce/platform-sdk/ui-embedding";
  1. Handle the component’s ready and error lifecycle events on your wrapper. The embedding component reports its lifecycle through DOM events, so listen for them so your wrapper can respond when the app is ready or when embedding fails.
  • sf-embedding.component.ready fires when the embedded app finishes loading and is ready to interact with Salesforce.
  • sf-embedding.component.error fires when embedding fails. The event detail includes the phase (configuration or bootstrap), an error code, a message, and whether the error is retryable. For the full list of codes, see UI Embedding Error Codes.

These event names contain dots, so you can’t bind them declaratively with on* attributes in the template. Add lwc:ref to the embedding element and attach the listeners imperatively in renderedCallback.

1<!-- myEmbeddedApp.html -->
2<template>
3  <lightning-ui-embedding src="{appUrl}" lwc:ref="embedding"></lightning-ui-embedding>
4</template>
1// myEmbeddedApp.js
2import { LightningElement } from "lwc";
3
4export default class MyEmbeddedApp extends LightningElement {
5  appUrl = "https://app.example.com";
6  hasWiredEvents = false;
7
8  renderedCallback() {
9    if (this.hasWiredEvents) {
10      return;
11    }
12    this.hasWiredEvents = true;
13
14    const el = this.refs.embedding;
15    el.addEventListener("sf-embedding.component.ready", this.handleReady);
16    el.addEventListener("sf-embedding.component.error", this.handleError);
17  }
18
19  handleReady = () => {
20    // The embedded app is ready.
21  };
22
23  handleError = (event) => {
24    const { code, message } = event.detail;
25    // Handle the failure.
26  };
27}
  1. In your embedded app, create the view SDK to read UI state and use the embedding features. createViewSDK is asynchronous, and off an embedding surface it resolves to an empty object, so guard the calls you make on it.
1import { createViewSDK } from "@salesforce/platform-sdk/view";
2
3const viewSdk = await createViewSDK();
4const uiState = viewSdk.getUiState?.();

With the view SDK in place, continue with the common tasks:

Path 2: Configure Without a Salesforce Package 

On this path, your app doesn’t take a dependency on any Salesforce package. Instead, your app implements the sf-embedding protocol directly: it completes the handshake, then sends and receives the protocol messages itself. Choose this path when you can’t add a Salesforce package to your app’s build, or when you want full control of the communication layer.

The lightning-ui-embedding component and the domain-trust and page setup are identical to the with-package path. The difference is entirely inside your app, where you build the communication bridge by hand.

For the full walkthrough, including the handshake, the protocol message catalog, error handling, and security requirements, see Build the Embedding Bridge Without a Salesforce Package.

Scaffold a Starter Component from the CLI 

Instead of writing the wrapper by hand, generate one with the Salesforce CLI. The sf template generate ui-embedding command scaffolds an embedding-ready Lightning web component bundle.

1sf template generate ui-embedding --name myEmbeddedApp --src https://app.example.com

The command creates a Lightning web component bundle configured for embedding. The bundle includes the HTML, JavaScript, metadata, and CSS files. Then edit the generated component and add it to a page as described earlier.

This command requires a recent version of the Salesforce CLI. If the command isn’t available, update the CLI, then run sf template generate ui-embedding --help to see the current flags and syntax.

Note

See Also