Refused to display in iframe: X-Frame-Options or CSP frame-ancestors
The error
Refused to display 'https://example.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
What it means
The page you’re trying to embed is configured to refuse iframe embedding from other sites. This is intentional protection against clickjacking.
X-Frame-Options: DENY blocks all framing. SAMEORIGIN allows only same-origin frames. Modern sites use CSP frame-ancestors instead — same effect. Without your site listed in the framed page’s policy, the browser refuses to render.
The fix
// app/middleware.ts (Next.js) — to allow yoursite.com to embed this page:
export function middleware(req: NextRequest) {
const res = NextResponse.next();
res.headers.set(
'Content-Security-Policy',
"frame-ancestors 'self' https://yoursite.com",
);
// remove the legacy header — it conflicts with frame-ancestors
res.headers.delete('X-Frame-Options');
return res;
}Also check
Common adjacent root causes when the obvious fix doesn’t work.
- 01You may not control the framed page (e.g. you’re embedding YouTube, Stripe Checkout). In that case, redirect the user instead of framing.
- 02If you control both pages, prefer CSP frame-ancestors over X-Frame-Options. The legacy header has no syntax for multiple origins.
- 03Setting both headers with conflicting values? Browsers prefer CSP. Remove X-Frame-Options.
Scan for related issues
This error is in our headers scanner. Run a free scan to find what else is misconfigured in the same area.
FAQ
Frequently asked questions
- I added frame-ancestors but it still blocks. Why?
- Browsers honor the strictest of X-Frame-Options and CSP frame-ancestors. Make sure both allow framing — or, better, remove X-Frame-Options entirely and rely on CSP.
- Is allowing framing dangerous?
- It can be — clickjacking attacks rely on framing your site over a malicious one. Only allow specific trusted origins, never "*".
Related fixes
Tighten this area further
Missing X-Frame-Options
Without X-Frame-Options or CSP frame-ancestors, attackers can embed your site in an invisible iframe to trick users into clicking things. Here is the fix.
Read moreMissing CSP header
A missing Content-Security-Policy header lets attackers inject scripts into your site. Here is what CSP does, why you need it, and how to add it in Next.js, Vercel, and Supabase apps.
Read moreBackground
Concepts
X-Frame-Options
A response header that stops other sites from embedding your page in an iframe, preventing clickjacking attacks.
Read moreContent Security Policy
CSP is a browser feature that tells your site which scripts, styles, and images are allowed to run. It is the main defense against cross-site scripting (XSS).
Read more