An iframe in Salesforce is an HTML inline frame that loads a page from another origin inside a Salesforce page, and Salesforce now has an official component for doing that with your own web app. That component is lightning-ui-embedding, part of the generally available UI Embedding feature. For a SaaS company, the real decision is not whether iframes work. It is which route gets your product in front of a customer's sales or service team. The candidates are a plain iframe, UI Embedding and a Canvas app. The fourth is a native Lightning web component that reads and writes Salesforce data directly.
Each route changes what you ship in a managed package, what the customer's admin has to set up at install, and what your enterprise buyers will call "native." Appnigma builds that native layer for SaaS teams. Its marketplace apps work promises "Your product, inside Salesforce or HubSpot." It covers the native app itself, plus listing preparation and review support. If you are an admin who only needs a dashboard on a record page, the sections on Trusted URLs and the "refused to connect" error answer your question on their own.
Updated October 2026. Checked against Salesforce's UI Embedding guide, the Lightning Web Security guide, the Canvas Developer Guide and the Metadata API reference. The earlier version named a "lightning-iframe" component that Salesforce does not have, described Canvas as passing a JWT, and said Salesforce blocks all framing of org pages. Salesforce documents something different on all three, so those claims are gone. This update adds UI Embedding, the packaging rules for Trusted URLs and the third-party cookie problem.
Where an iframe can live in a Salesforce org
Salesforce gives you six places to put a frame, and they differ in who builds them and what the frame can see. The table maps each one to its official page.
| Route | How it is built | Who it suits | What to know |
|---|---|---|---|
| Plain <iframe> in a Lightning web component | Standard HTML in the component template | Read-only views, quick embeds | The target needs a Trusted URL with frame-src and must be HTTPS |
| UI Embedding | lightning-ui-embedding inside a thin wrapper component | A SaaS product's own web app | Generally available, Hyperforce orgs with English as the default language |
| Visualforce | apex:iframe or an HTML iframe in a page | Older packages and Classic users | In Lightning Experience the Visualforce page itself already runs in an iframe |
| Canvas app | Canvas settings on an external client app or connected app | Apps that need a signed Salesforce context on load | Several locations work in Salesforce Classic only |
| Web tab | A custom tab whose URL points at an external page | Admins linking a whole external site | Set up in Setup, and no Salesforce context reaches the page |
| Lightning Out 2.0 | Salesforce components embedded in your external site | The reverse direction, Salesforce inside your app | Each component loads in an iframe and needs third-party cookies |
The first three rows come from the LWC third-party component page, the UI Embedding guide and apex:iframe. The rest come from Where Canvas Apps Appear, the CustomTab metadata type and the Lightning Out 2.0 comparison. There is no base component called lightning-iframe. A plain iframe in a component template is ordinary HTML, and the only base component built for framing an external app is lightning-ui-embedding.
Why does a Salesforce iframe refuse to connect?
A Salesforce iframe usually refuses to connect for one of four reasons, and the browser console tells you which one. Work through them in this order.
- The origin is not a Trusted URL. In Lightning Experience, frame content "must be located in the org by default," per the Content Security Policy overview. Add the target origin under Trusted URLs, the Setup page that used to be called CSP Trusted Sites, and tick the frame-src directive. The CspTrustedSite reference says frame-src "has a default value of
false," so a Trusted URL saved with only img-src still blocks the frame. - The URL is not HTTPS. The same overview says "All references to external fonts, images, frames, and CSS must use an HTTPS URL."
- The target page forbids framing. Many sites send
X-Frame-Optionsor a CSP frame-ancestors header. The apex:iframe page explains that withsameorigin"a browser can only load that page in an inline frame if the frame has the same origin as the page." Only the owner of the target site can change that header. - The login needs a cookie the browser won't send. A framed page from another domain gets third-party cookies, and Salesforce notes that browser settings can stop it "receiving or writing third-party cookies in callouts to APIs." The page loads, then lands on its own login screen or a blank state.
Wildcards help with the first cause. The CspTrustedSite reference allows *.example.com, so one entry can cover a product that serves each customer from its own subdomain.
How UI Embedding puts a SaaS web app inside Lightning
UI Embedding is the route Salesforce built for exactly this job. Salesforce "hosts your app inside a secure, sandboxed iframe by using the lightning-ui-embedding base component," per Get Started with UI Embedding. You write a thin Lightning web component that wraps it, place that component on a Lightning page or an Experience Cloud site, and trust your app's origin in Setup.
<!-- myEmbeddedApp.html -->
<template>
<lightning-ui-embedding src={appUrl} title="Acme workspace"></lightning-ui-embedding>
</template>The same page shows a CLI shortcut, sf template generate ui-embedding --name myEmbeddedApp --src https://app.example.com, that scaffolds the wrapper bundle. Your web app then talks to the page over the sf-embedding protocol, either through the @salesforce/platform-sdk package or a bridge you write yourself. The data exchange page says both directions use "the same versioned sf-embedding channel, so you don't manage postMessage calls or origins yourself."Org eligibility is the first thing to check. The guide names five editions, from Enterprise and Unlimited to Partner Developer. It also requires "orgs hosted on Hyperforce where English is the default language." Run your largest customers against that sentence before you plan a release around UI Embedding.
Your login stays yours. The package-free bridge page says "The host gives you no credentials or data access, so authenticate to your own backend as usual." It also warns "There's no bootstrap timeout," because the frame may sit on your login or MFA screen first. That makes UI Embedding a fit for products that already run SSO for enterprise customers.
Two limits shape the hosting. "A same-origin src is rejected with a SAME_ORIGIN_SRC error," so your app can't be served from the org's own domain. The error code reference also blocks allow-top-navigation and allow-popups-to-escape-sandbox in the sandbox attribute, so the frame can't take over the browser tab.
UI Embedding replaced a Developer Preview built on lwc-shell. Salesforce's migration page says "The Developer Preview and generally available APIs aren't compatible," so any tutorial using the old element is out of date.
Salesforce Canvas vs iframe vs UI Embedding
Canvas, a plain iframe and UI Embedding all show an external page inside Salesforce. What they differ on is what Salesforce hands your app when the frame opens.
| Question | Plain iframe | UI Embedding | Canvas app |
|---|---|---|---|
| What your app receives on load | Only the URL you built | UI state and props over the sf-embedding channel, no credentials | A signed request with user, org context and an OAuth token |
| How the app authenticates | Your own login | Your own login | Verify the signed request, or use OAuth web server or user-agent flow |
| Talking back to the page | Your own postMessage code | SDK or protocol bridge, versioned | Canvas SDK |
| Where it shows | Any LWC placement | Lightning pages and Experience Cloud sites | Page layouts, Visualforce, Chatter feed, mobile, actions. Some spots are Classic only |
| Setup in the customer org | Trusted URL with frame-src | Trusted origin plus a wrapper component on a page | Canvas app settings, permitted users, OAuth policies |
The Canvas signed request is often described as a JWT. It isn't one. Salesforce's signed request page lists the parts as an HMAC SHA-256 signature made with the consumer secret and "The context and authorization token JSON encoded in Base64." Your server checks it with the steps in Verifying and Decoding a Signed Request. Signed request is the default, and the OAuth page says "Canvas supports the OAuth 2.0 web server flow and the OAuth 2.0 user-agent flow."
Canvas also moved in 2026. "Starting in Spring '26, we recommend that you use external client apps for your canvas integrations," per the Canvas quick start. The create page adds that "In Spring '26, the ability to create new connected apps is disabled by default." An external client app with Canvas ships in a managed 2GP package, per Package Your Canvas App.
The practical split is simple. Pick Canvas when your app needs Salesforce identity and an API token the moment it loads. Pick UI Embedding when your app already has its own login and you want a supported channel to the page. A plain iframe fits read-only views where neither matters.
What changes when the frame ships in a managed package
A managed package can carry the wrapper Lightning web component and even the Trusted URL, but Salesforce advises against packaging the Trusted URL. The packageable components list marks CspTrustedSite as packageable in 1GP and 2GP, then says "we don't recommend including CspTrustedSite components in packages." If you include it anyway, Salesforce asks you to "disclose this change prominently in your package documentation."
So the usual install looks like this. The package installs the component, your setup guide asks the admin to add your origin as a Trusted URL with frame-src, and the admin places the component in Lightning App Builder. That is three steps a customer's admin must finish before the first user sees anything. Most "the app is blank" tickets after install trace back to the second step.
Per-customer subdomains need one line in the setup guide. If each customer gets customer.app.example.com, one wildcard entry covers all of them, but an admin who types the bare domain gets a blocked frame.
Scripts are a separate rule. A Trusted URL doesn't let your component load JavaScript from your servers. The same packaging page says "You can't load JavaScript resources from a third-party site, even if it's a CSP Trusted Site." Ship those scripts as a static resource in the package.
UI Embedding eligibility also varies by customer. Because it requires Hyperforce and an English default language, a package that depends on it needs a fallback for orgs outside that list, or a clear statement in the listing.
Here is a worked example of what an iframe-only package costs a customer in setup, using only the steps above. A customer with three Lightning record pages that should show your panel needs one Trusted URL entry and three App Builder edits. If they run an Experience Cloud site as well, add a fourth placement in Experience Builder. None of it is hard, but none of it can ship pre-done in the package, so your onboarding has to carry it.
Framing Salesforce inside your own app
The reverse case, a Salesforce page inside your product, runs on different settings. Salesforce's security FAQ says "By default, Visualforce pages can be loaded in an iframe," and that "The CSP frame-ancestors header directive replaces the obsolete X-Frame-Options header," per Platform Security FAQs. Admins lock that down with clickjack protection and then list the sites allowed to frame the org.
The setup sits under Session Settings. Put Visualforce Pages on External Domains tells admins to "add the trusted external domains where you allow framing and set the iframe type to Visualforce Pages," and notes "You can add up to 512 external domains." The same page explains the catch for logged-in pages. "Because browsers block third-party cookies, framing an authenticated Visualforce page requires additional steps." Salesforce recommends serving the framed content from a custom domain on the same registrable domain as your site, and if that isn't possible, opening the page in a new window instead.
Lightning Out 2.0 is the generally available way to place Lightning web components on an external site. Each component "loads in an iframe and is encapsulated in a closed shadow Document Object Model (DOM)," per the comparison page. The limitations page adds that it "requires third-party, or cross-origin, cookies" and is "currently only available to authenticated Salesforce users." If your product's users don't all hold Salesforce logins, it isn't the right fit.
Security rules an iframe has to follow
Salesforce's secure coding guide is the reference AppExchange reviewers work from, and it names specific iframe patterns. None of them is exotic, and each one shows up in a first package more often than you would expect.
- No `javascript:` in a frame `src`, and no `srcdoc`. Both appear as unsafe sinks in the Lightning Security page. Lightning Web Security enforces part of this already. The LWS iframe page says it "restricts the
srcattribute foriframeelements to values that use thehttp://andhttps://schemes." - **Never post to
"*".** The postMessage guidance calls a wildcard target "an insecure use of postMessage API." Receivers should "accept messages only from domains on an allowlist." LWS keeps the frame's identity so that this origin check "works normally." - No Salesforce session ID in the frame URL. The storing sensitive data page says "Don't send a Salesforce session ID or any PII data over a URL to external applications." Use OAuth, a Canvas signed request, or your own login.
- No `position: fixed` or `position: absolute` in shared components. The clickjacking page asks you not to use them "within the CSS of externally exposed or shared components," because a floating layer over another component is the same risk as a hidden frame.
A note on old advice. Lightning Locker blocked access to iframe content even from the same origin. Under Lightning Web Security, components "can access content in iframe elements when the content is from the same origin," and postMessage is allowed across origins, per the LWS iframe page. Code written around Locker's limits can usually be simplified.
When an iframe is the wrong answer for a SaaS product
An iframe shows your product inside Salesforce, but the data stays in your product. Your customer's reports, flows, list views and sharing rules can't see what lives in the frame. That gap is usually what enterprise buyers mean when they ask whether an app is native.
When the requirement is data, other tools fit better. A Lightning web component that calls your API through Apex keeps the UI in Salesforce styling and lets you write results to Salesforce records. Salesforce Connect shows your records as external objects. The Apex connector docs say external objects start as read only and "you can make them writable" when the use case needs it. Support chat has its own path. Salesforce scheduled the legacy Chat product for retirement on February 14 2026, per a Service SDK note, so new builds belong on Messaging for In-App and Web.
Many SaaS teams do both. A UI Embedding panel brings the full product into the record page, and a small native layer syncs the fields buyers report on. That pairing is the kind of build Appnigma's done-for-you integrations cover, with a named integration engineer and ongoing maintenance.
Mistakes that leave the frame blank after install
Five mistakes leave an embedded frame blank after a customer installs a Salesforce package that uses an iframe. Each one looks like a broken app to the end user, and none of them is fixed by reinstalling.
- Trusted URL saved without frame-src. The entry exists, the frame still fails, and the admin assumes your app is down.
- Bare domain instead of the wildcard.
app.example.comis trusted while the customer's tenant lives onacme.app.example.com. - Your own site sends `X-Frame-Options: DENY`. Your app has to allow framing by the customer's Lightning domain through frame-ancestors, or no Salesforce setting helps.
- Login depends on a third-party cookie. Safari and other browsers that block those cookies show a login loop inside the frame.
- Lightning Message Service from an iframed Visualforce page. Salesforce states that it "doesn't work in Visualforce pages that are included in Lightning Experience via iframes," per the message channel considerations.
Frequently Asked Questions
What is an iframe in Salesforce?
It is an HTML inline frame that shows a page from another origin inside a Salesforce page. You can add one in a Lightning web component, a Visualforce page, a web tab, or through UI Embedding and Canvas.
Is there a lightning-iframe component?
No. Salesforce's iframe base component is lightning-ui-embedding, and a plain <iframe> tag in a component template is standard HTML that needs a Trusted URL with frame-src.
Should a SaaS app use Canvas or an iframe?
Use Canvas when your app needs Salesforce identity and an OAuth token on load. Use UI Embedding when your app keeps its own login, and a plain iframe only for read-only views.
Can a managed package include the Trusted URL?
Yes, CspTrustedSite is packageable in 1GP and 2GP. Salesforce recommends leaving it out and having the customer's admin add it, and asks you to disclose it prominently if you package it.
Can Appnigma build the Salesforce side of our embedded app?
Yes. Appnigma's marketplace apps work covers "a native app, marketplace listing preparation, and review support," built by ex-Salesforce engineers.
About the author
Sunny Chauhan is the co-founder and CEO of Appnigma AI, which builds and maintains customer integrations and native Salesforce and HubSpot apps for B2B SaaS teams. Before Appnigma, he was on Salesforce's AppExchange team, where he worked with more than 300 SaaS partners. He has spent close to a decade on the Salesforce platform, including work at Zennify, and holds Salesforce certifications including Platform Developer II, Platform App Builder, Administrator, Data Cloud Consultant, and AI Associate.
Related Articles
- What a native Salesforce app is and how it differs from a connector
- Creating and upgrading a managed package
- How the Salesforce security review works
- Named credentials and external credentials in a package
- Connecting one SaaS app to many customer orgs with OAuth
Sources
- Get Started with UI Embedding and Exchange Data Between the Page and an Embedded App
- Build the Embedding Bridge Without a Salesforce Package, UI Embedding Error Codes and Migrate from the Developer Preview API
- Access to iframe Content in Lightning Web Security and Content Security Policy Overview
- CspTrustedSite metadata type and Components Available in Managed Packages
- apex:iframe and Put Visualforce Pages on External Domains
- Signed Request Authentication, Verifying and Decoding a Signed Request and Where Canvas Apps Appear
- Canvas quick start with external client apps and Package Your Canvas App
- How Lightning Out 2.0 Compares to Lightning Out (Beta) and Lightning Out 2.0 Limitations
- Platform Security FAQs, Understand Clickjacking and Lightning Security
- Secure postMessage usage and Storing Sensitive Data
- Writable External Objects and Lightning Message Service Considerations



