Figma embeds are one of those things that look trivial until your CSP blocks them and you end up staring at a blank iframe.
If you’re embedding a Figma file, prototype, or board on your site, the CSP piece is usually small but annoyingly specific. The main directive you need is frame-src. Sometimes you also need to think about child-src, frame-ancestors, and the fact that Figma itself loads its own resources inside the iframe, not in your page context.
Here’s the practical rule:
- Your page needs permission to load a Figma iframe
- Figma’s internal scripts, styles, and network calls are governed by Figma’s CSP, not yours
- Your CSP only controls whether the browser is allowed to embed
https://www.figma.com/...at all
The minimum CSP for a Figma embed
If your page already has a CSP and you want to allow Figma embeds, this is the smallest useful addition:
Content-Security-Policy: default-src 'self'; frame-src https://www.figma.com;
That allows iframes from Figma and nothing else beyond your own origin by default.
A matching HTML embed might look like this:
<iframe
style="border: 1px solid rgba(0, 0, 0, 0.1);"
width="800"
height="450"
src="https://www.figma.com/embed?embed_host=share&url=https://www.figma.com/file/FILE_ID/Example"
allowfullscreen>
</iframe>
If frame-src does not include https://www.figma.com, the browser will block it.
The directive that matters: frame-src
For Figma embeds, frame-src is the directive you almost always need.
Content-Security-Policy: frame-src https://www.figma.com;
If your policy uses default-src and does not specify frame-src, then frames inherit from default-src. That means this policy will block Figma:
Content-Security-Policy: default-src 'self';
Because https://www.figma.com is not 'self'.
If you want a simple working baseline:
Content-Security-Policy:
default-src 'self';
frame-src 'self' https://www.figma.com;
object-src 'none';
base-uri 'self';
I like this pattern because it stays tight while still being obvious to the next developer.
child-src vs frame-src
Some older CSP setups still use child-src. Modern browsers use frame-src for frames, but if you support legacy behavior or inherited policies from older apps, you may want both.
Content-Security-Policy:
default-src 'self';
child-src https://www.figma.com;
frame-src https://www.figma.com;
If you’re cleaning up an old policy, I’d keep frame-src as the source of truth and only include child-src if you know you need backward compatibility.
For deeper directive behavior, the CSP reference at csp-guide.com is useful.
Copy-paste policies
1. Minimal Figma embed policy
Use this if the page is mostly static and only needs the iframe.
Content-Security-Policy:
default-src 'self';
frame-src https://www.figma.com;
object-src 'none';
base-uri 'self';
2. Typical app page with scripts, styles, and Figma
Use this if your app already has local JS and CSS.
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self';
frame-src 'self' https://www.figma.com;
object-src 'none';
base-uri 'self';
form-action 'self';
3. Based on a real production-style header
You gave a real header from headertest.com. If you want to adapt that kind of policy to support Figma, the change is small: add Figma to frame-src.
Original style:
content-security-policy: default-src 'self' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com; script-src 'self' 'nonce-OGJjYWVkNmUtMjUzMC00M2Y0LWJiN2EtZGJjNTM5Yzg2MDAx' 'strict-dynamic' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com; style-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://*.cookiebot.com https://consent.cookiebot.com; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.headertest.com https://tallycdn.com https://or.headertest.com wss://or.headertest.com https://*.google-analytics.com https://*.googletagmanager.com https://*.cookiebot.com; frame-src 'self' https://consentcdn.cookiebot.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'
Updated for Figma embeds:
Content-Security-Policy:
default-src 'self' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com;
script-src 'self' 'nonce-OGJjYWVkNmUtMjUzMC00M2Y0LWJiN2EtZGJjNTM5Yzg2MDAx' 'strict-dynamic' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com;
style-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://*.cookiebot.com https://consent.cookiebot.com;
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.headertest.com https://tallycdn.com https://or.headertest.com wss://or.headertest.com https://*.google-analytics.com https://*.googletagmanager.com https://*.cookiebot.com;
frame-src 'self' https://consentcdn.cookiebot.com https://www.figma.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
object-src 'none';
That’s usually all you need.
Do you need connect-src for Figma?
Usually, no.
This trips people up a lot. The Figma app running inside the iframe makes its own requests under Figma’s origin and CSP. Your page does not need connect-src https://www.figma.com just to display the embed.
You only need to expand connect-src if your own page JavaScript talks to Figma APIs directly.
Example:
fetch("https://api.figma.com/v1/files/FILE_ID", {
headers: {
"X-Figma-Token": "YOUR_TOKEN"
}
});
That would require something like:
Content-Security-Policy: connect-src 'self' https://api.figma.com;
But that is unrelated to the iframe embed itself.
frame-ancestors does not allow Figma embeds
frame-ancestors is for controlling who can embed your page.
I still see developers try this:
Content-Security-Policy: frame-ancestors https://www.figma.com;
That does not permit loading a Figma iframe on your page.
frame-src= what your page may embedframe-ancestors= who may embed your page
If your site should never be embedded by anyone, keep this:
Content-Security-Policy: frame-ancestors 'none';
That is perfectly compatible with embedding Figma on your own page.
Common mistakes
Mistake 1: Only updating default-src
Some teams assume this is enough:
Content-Security-Policy: default-src 'self' https://www.figma.com;
It can work if frame-src is absent, but I don’t like relying on fallback behavior when the intent is specifically about frames. Be explicit:
Content-Security-Policy:
default-src 'self';
frame-src 'self' https://www.figma.com;
Mistake 2: Using the wrong Figma origin
Use:
frame-src https://www.figma.com;
Not random subdomains unless you have a specific reason. Keep it narrow.
Mistake 3: Trying to fix the embed with script-src
Your page does not execute Figma’s iframe scripts in your origin, so this does nothing for the embedding problem:
script-src 'self' https://www.figma.com;
If the iframe is blocked, the fix is almost always frame-src.
Mistake 4: Forgetting report-only rollout
If you’re changing CSP on a production app, test with report-only first.
Content-Security-Policy-Report-Only:
default-src 'self';
frame-src 'self' https://www.figma.com;
report-to csp-endpoint;
That lets you see violations before enforcing them. The reporting setup depends on your stack, but the rollout strategy is worth it.
Official CSP docs are here: MDN Content-Security-Policy
Nginx example
add_header Content-Security-Policy "default-src 'self'; frame-src 'self' https://www.figma.com; object-src 'none'; base-uri 'self';" always;
Apache example
Header always set Content-Security-Policy "default-src 'self'; frame-src 'self' https://www.figma.com; object-src 'none'; base-uri 'self';"
Express / Node example
app.use((req, res, next) => {
res.setHeader(
"Content-Security-Policy",
"default-src 'self'; frame-src 'self' https://www.figma.com; object-src 'none'; base-uri 'self';"
);
next();
});
Helmet example
import helmet from "helmet";
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
frameSrc: ["'self'", "https://www.figma.com"],
objectSrc: ["'none'"],
baseUri: ["'self'"]
}
})
);
Fast troubleshooting checklist
If the Figma embed is blank or blocked, I check these first:
- Browser console says CSP blocked a frame
frame-srcis missinghttps://www.figma.com- A stricter meta CSP is overriding the header
- The embed URL is malformed
- The Figma resource itself does not allow the kind of sharing you expect
A good final baseline for most sites is this:
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self';
frame-src 'self' https://www.figma.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
If all you need is Figma embeds, don’t overcomplicate it. Add https://www.figma.com to frame-src, keep the rest of the policy tight, and move on.