Headers

X-Frame-Options vs CSP frame-ancestors โ€” Which to Use in 2026

Updated April 2026

Reading this article? Verify your fix in real-time. Test your config live โ€” HttpFixer โ†’

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-OptionsCSP frame-ancestors
Browser supportAll browsers including IEAll modern browsers
Multiple originsโŒ Noโœ… Yes
Wildcard supportโŒ Noโœ… Yes (https://*.example.com)
Takes precedenceIgnored when CSP presentWins over X-Frame-Options
Works in meta tagNoNo (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

Check your frame protection โ†’ HeadersFixer
Compare headers between staging and production โ†’ Header Diff