Skip to main content

Salesforce Remote Site Settings vs. CSP Trusted Sites Explained

Updated Add a comment
💬 In plain words: Think of these as two completely separate security allow-lists that guard different doors. Remote Site Settings give your Salesforce backend server (Apex or Flow HTTP Callout) permission to call an external URL. CSP Trusted Sites (now grouped under Trusted URLs in Salesforce Setup) give the user's web browser (LWC or Aura) permission to fetch data, images, or scripts from an external URL. If an Apex callout fails, check Remote Site Settings or Named Credentials. If a browser request fails inside an LWC, check your CSP Trusted Sites!
📌 Real-Life Example: Imagine you are building a live weather dashboard on an Account page. First, your Apex class tries to fetch weather data from https://api.weather.com, and Salesforce immediately throws a System.CalloutException: Unauthorized endpoint error. Why? Because the Salesforce server blocked the call. The fix is adding a Remote Site Setting (or better yet, a Named Credential).

Later that day, you add an interactive weather map inside your Lightning Web Component (LWC) that loads map images directly from https://maps.weather.com. Suddenly, the map shows a blank box and your Chrome developer console screams about a Content Security Policy violation. Why? Because the user's browser blocked the image! The fix is adding a Trusted URL (CSP Trusted Site). Both errors look like blocked URLs, but they happen in two completely different places.

🧱 Key Points: Server-Side vs. Browser-Side Security

Developers mix up Remote Site Settings and CSP Trusted Sites all the time because both settings ask you to paste an external URL into Salesforce Setup. The secret to never confusing them again is asking one simple question: Where is the HTTP request starting from?

  • 🖥️ Remote Site Settings Guard the Server: Whenever your Apex code runs Http.send() with a hardcoded URL string, Salesforce's backend server checks Remote Site Settings before letting the traffic leave its data center.
  • 🔐 Named Credentials Are the Modern Server Standard: In modern Salesforce architecture, you should avoid raw Remote Site Settings whenever possible. Instead, use Named Credentials paired with External Credentials. When you reference a Named Credential in Apex (or inside a declarative Flow HTTP Callout), Salesforce automatically authorizes the endpoint—no Remote Site Setting required!
  • 🌐 Trusted URLs (CSP Trusted Sites) Guard the Browser: When your LWC JavaScript runs fetch(), embeds an external <iframe>, or loads an external image or font, the request starts directly inside the user's Chrome, Edge, or Safari browser. Salesforce's Content Security Policy (CSP) blocks all unknown external domains in the browser until you whitelist them under Setup > Trusted URLs (formerly called CSP Trusted Sites).
  • 🎯 Granular CSP Directives Matter: When creating a Trusted URL in Setup, you don't have to open every door at once. Salesforce lets you check specific CSP boxes like connect-src (for JavaScript fetch and XMLHttpRequest calls), img-src (for images), script-src (for external JS), or frame-src (for iframes).
  • 🤝 Browser Calls Also Need CORS on the Other Side: Whitelisting a URL in CSP Trusted Sites only tells the user's browser that Salesforce trusts the external server. That external server must also include your Salesforce domain in its CORS (Cross-Origin Resource Sharing) response headers (Access-Control-Allow-Origin), or the browser will still block your LWC from reading the response!
  • 📦 Static Resources Bypass CSP Headaches for Scripts: Instead of loading third-party JavaScript libraries (like Chart.js or D3.js) from a public CDN URL using CSP, Salesforce best practice requires uploading the library as a Static Resource and loading it via lightning/platformResourceLoader.
🧠 Core Takeaway: Remote Site Settings (and Named Credentials) authorize SERVER-SIDE Apex callouts. Trusted URLs (CSP Trusted Sites) authorize BROWSER-SIDE LWC requests!

⚖️ Quick Comparison: Remote Site Setting vs. CSP Trusted Site

Feature Remote Site Setting CSP Trusted Site (Trusted URLs)
Where Traffic Starts Salesforce Backend Server (Apex) User's Web Browser (LWC / Aura)
Needed For Http.send() to a raw endpoint URL JavaScript fetch(), external images, fonts, frames
Modern Replacement Named Credentials & External Credentials Still required (configured under Trusted URLs)
Where Error Appears Apex Debug Logs (Unauthorized endpoint) Browser DevTools Console (CSP violation)
Also Requires Nothing else for URL whitelisting Remote server must allow your domain via CORS
⚠️ INTERVIEW & ARCHITECTURE TRAP: Never tell an interviewer that you would add a Remote Site Setting to fix a blocked JavaScript fetch() call inside an LWC! Even worse, never store secret API keys or OAuth client secrets inside LWC JavaScript to make a browser callout—any user can open Chrome DevTools and steal your keys in 5 seconds. If an external API requires secret credentials, always call it from the server using Apex (or Flow) and a Named Credential!

🧭 The 360 Card: Outbound Security Allow-Lists

📏 The Golden Rule: Remote Site Settings and Named Credentials unlock the Salesforce server. Trusted URLs (CSP) unlock the user's browser.

🎁 The Gain: Knowing whether an error is happening on the server or in the browser turns a frustrating 2-hour debugging session into a 30-second configuration fix.

💸 The Price: Because their names sound so similar, developers frequently whitelist a URL in Remote Site Settings when the block is actually happening in the browser's CSP—wasting hours wondering why their LWC still fails.

🛑 The Limits: A Named Credential eliminates the need for a Remote Site Setting on the server side, but it does nothing for browser-side LWC fetch() requests. Browser calls always require a Trusted URL entry plus external CORS support.

🏆 Best Practice: For external JS libraries or CSS stylesheets, don't use CSP Trusted Sites at all. Download the files, upload them as a Salesforce Static Resource, and load them locally with loadScript() so your component loads fast and passes security reviews effortlessly.

💬 Core Q&A & Interview Prep

Q1: A Lightning Web Component calls an external API directly using JavaScript fetch() and gets blocked. Which setting fixes it, and why doesn't a Remote Site Setting help?

🎯 Say this first: "You need to configure a Trusted URL (CSP Trusted Site) with the connect-src directive enabled, and ensure the external API server allows our Salesforce domain in its CORS policy. A Remote Site Setting won't help because the request is coming directly from the user's web browser, never touching the Salesforce Apex server."

When an LWC executes fetch('https://api.example.com/data'), the HTTP request travels straight from the user's laptop to the external API server. Because it runs in the browser, two separate security guards inspect the call:

  • 1. Salesforce Content Security Policy (Trusted URLs): By default, Lightning Experience and Experience Cloud pages send strict CSP headers to the browser that forbid JavaScript from talking to unknown outside domains. Adding the external URL to Setup > Trusted URLs (and checking the connect-src (scripts) box) tells the browser that your Salesforce page is allowed to call that URL.
  • 2. External Server CORS Headers: Even after you add the CSP Trusted Site, the browser checks if the external server returned an Access-Control-Allow-Origin header matching your Salesforce domain (or * for public APIs). If the external server doesn't include that CORS header, the browser hides the response from your LWC!

Remember: only use direct browser fetch() for 100% public, unauthenticated APIs (like public currency rates or postal code lookups). If the API needs an API key or Bearer token, route the call through an @AuraEnabled Apex method backed by a Named Credential!

// ============================================================================
// ✅ PATH 1: Server-Side Callout via Apex + Named Credential (Preferred & Secure)
// Requires: Named Credential (NO Remote Site Setting or CSP needed!)
// Best for: Authenticated APIs with secret keys, OAuth tokens, or no CORS support
// ============================================================================
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Weather_Named_Credential/v1/forecast');
req.setMethod('GET');
HttpResponse res = new Http().send(req);

// ============================================================================
// 🌐 PATH 2: Browser-Side Callout via LWC JavaScript fetch() (Public APIs Only)
// Requires: Trusted URL / CSP Trusted Site (connect-src) + External Server CORS
// Best for: Public, unauthenticated endpoints that return CORS headers
// ============================================================================
const response = await fetch('https://api.public-rates.com/v1/latest');
const data = await response.json();

🔗 Connecting the Dots: Scenario-Based Follow-Ups

Q2: You added a Remote Site Setting, but your Apex callout still fails with a "System.CalloutException: Unauthorized endpoint" error. What did you miss?

When a Remote Site Setting fails to stop an Unauthorized endpoint error in Apex, check these four sneaky culprits right away:

  • 🔍 Protocol or Subdomain Mismatch: Remote Site Settings are picky about exact domains and protocols. If you whitelisted https://example.com, but your Apex code calls https://api.example.com (or http://example.com without SSL unless Disable Protocol Security is checked), Salesforce will block it.
  • 🔀 Hidden HTTP 301/302 Redirects: Sometimes your Apex code calls https://api.oldvendor.com, and that server automatically redirects the request to https://api.newvendor.com. You must whitelist both the original domain and the redirect destination domain!
  • 💤 The "Active" Checkbox Is Unchecked: It sounds silly, but developers frequently deploy a Remote Site Setting metadata file where <isActive>false</isActive> is accidentally set.
  • 💡 The Ultimate Fix: Stop fighting raw URLs and switch your Apex code to a Named Credential (callout:My_Named_Cred/path), which handles endpoint authorization and authentication in one clean package.

Q3: A third-party JavaScript charting library in your LWC refuses to load from a CDN. How do you diagnose and fix the CSP issue properly?

First, press F12 in your browser and look at the Console tab. A Content Security Policy block always prints a red error naming the exact violated directive—such as Refused to load the script 'https://cdn.example.com/chart.js' because it violates the following Content Security Policy directive: "script-src...".

However, do not just rush to Setup to whitelist that CDN in Trusted URLs! In modern Salesforce, loading executable <script> tags directly from external CDNs inside Lightning components is heavily restricted by Lightning Web Security (LWS) and will instantly fail a Salesforce AppExchange Security Review. Instead, follow the official Salesforce best practice:

  • Step 1: Download the .js file to your computer and upload it to Setup > Static Resources.
  • Step 2: Import loadScript from lightning/platformResourceLoader inside your LWC and load the file from @salesforce/resourceUrl/yourChartLibrary.

Loading the script from a Static Resource serves it directly from Salesforce's own domain—completely bypassing CSP Trusted Sites, avoiding external network outages, and keeping LWS happy!

Q4: Why do I need BOTH a CSP Trusted Site and CORS configuration for an LWC fetch() request?

Think of a browser fetch() call like crossing an international border between two countries: Salesforce and the External API Server.

  • 🛂 CSP Trusted Site (The Exit Visa): Configured inside Salesforce Setup. It tells your browser, "Salesforce gives this LWC permission to leave our page and talk to that external URL."
  • 🛂 CORS Policy (The Entry Visa): Configured on the external API server. It tells your browser, "The external server gives users coming from your specific Salesforce domain permission to read our data."

If you configure CSP in Salesforce, but the external API owner refuses to add your Salesforce URL (https://yourcompany.lightning.force.com) to their server's CORS allowlist, the browser will block your LWC from reading the response. And how do you fix it if you can't control the external server's CORS settings? Easy! Move the callout from LWC fetch() to an Apex class with a Named Credential—because server-to-server Apex calls completely ignore browser CORS rules!

Q5: In Salesforce Setup, why do I see "Trusted URLs" instead of "CSP Trusted Sites" in newer releases, and what is the difference between Salesforce CORS and Trusted URLs?

Salesforce renamed CSP Trusted Sites to Trusted URLs in Setup so admins can manage both Content Security Policy (CSP) directives and browser Permissions Policies (like microphone or camera access) in one unified screen. If an interview question asks about "CSP Trusted Sites," mention that it is now called Trusted URLs in Setup to show your knowledge is completely up to date!

Also, watch out for the Setup > CORS menu inside Salesforce! Many developers mistakenly add external API URLs to Salesforce's internal CORS menu thinking it will fix an outbound LWC fetch() error. It won't! Salesforce's internal CORS allowlist is for the exact opposite direction: it allows an external website's browser (like your company's React portal) to call inbound into Salesforce REST APIs!

Q6: Does an Experience Cloud (Community) site use the exact same CSP settings as internal Lightning Experience?

Not completely! While choosing All (or Communities) as the context inside Setup > Trusted URLs applies your CSP rules to Experience Cloud sites, LWR (Lightning Web Runtime) and Aura Experience Cloud sites also have their own security panel inside Experience Builder > Settings > Security > Content Security Policy (CSP). When your LWC is placed on a public or customer portal page, make sure you inspect Experience Builder's CSP security level and whitelist any required script or image hosts right there in Builder if needed!

Was this article helpful?

Have a question or spotted a mistake? Ask here about this article

Found this guide useful? Buy me a coffee (opens in a new tab)

Comments

Questions, corrections and your own experience are all welcome.