X-Frame-Options vs CSP frame-ancestors — Which to Use in 2026
X-Frame-Options and CSP frame-ancestors both control iframe embedding — but frame-ancestors is more powerful and takes precedence when both are set. Use both for maximum browser compatibility.
X-Frame-Options — the old way
X-Frame-Options: SAMEORIGIN # or DENY
Introduced in 2008. Supported by all browsers. Simple but limited — only SAMEORIGIN or DENY, no support for multiple allowed origins.
CSP frame-ancestors — the modern way
Content-Security-Policy: frame-ancestors 'none'; Content-Security-Policy: frame-ancestors 'self'; Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com https://embed.example.com;
Part of CSP Level 2. Supports multiple origins, wildcards, and more granular control. Takes precedence over X-Frame-Options in browsers that support CSP (which is basically all modern browsers).
Comparison
| X-Frame-Options | CSP frame-ancestors | |
|---|---|---|
| Browser support | All browsers including IE | All modern browsers |
| Multiple origins | ❌ No | ✅ Yes |
| Wildcard support | ❌ No | ✅ Yes (https://*.example.com) |
| Takes precedence | Ignored when CSP present | Wins over X-Frame-Options |
| Works in meta tag | No | No (frame-ancestors cannot be in meta) |
Use both for full coverage
# Nginx add_header X-Frame-Options "SAMEORIGIN" always; add_header Content-Security-Policy "frame-ancestors 'self';" always;
Modern browsers use frame-ancestors and ignore X-Frame-Options. Older browsers without CSP support fall back to X-Frame-Options. Using both gives you clickjacking protection regardless of browser version.
When to use DENY vs none
frame-ancestors 'none'/X-Frame-Options: DENY— no one can embed your page, including your own domain. Use for login pages, payment pages, sensitive actions.frame-ancestors 'self'/X-Frame-Options: SAMEORIGIN— your own domain can embed the page. Use when you have legitimate iframe use cases on your own domain.