X-Frame-Options
Definition
X-Frame-Options was introduced to stop a page being framed by a site its author does not control. DENY means no framing at all, including by the page's own site. SAMEORIGIN means only pages from the same origin may frame it. A third value, ALLOW-FROM followed by a URL, was defined but never implemented consistently and is ignored by current browsers, so treat it as unavailable. The header applies to the framed page, not the framing one — a site cannot use it to control what it embeds. It is a single, blunt switch with no list and no wildcards, which is both its virtue and its limit.
Why It Matters
The header exists to blunt clickjacking, where an attacker loads your page invisibly over their own and tricks a visitor into clicking your buttons. If your page has nothing to click that matters — a brochure, a PDF, a chart — framing is harmless and blocking it costs you legitimate embeds. If it has a login form, a delete button or a payment step, framing is a real risk and DENY is the right default. The trade-off bites in one direction people rarely anticipate: set DENY on a page you also want to embed in Notion or a client's intranet and the embed shows an empty box with a console error, with nothing on the embedding side to fix.
How It Works
The server sends X-Frame-Options with the HTML response. Before rendering the page inside a frame element, the browser reads the header from the framed document and either draws it or leaves the frame blank. Because it is an HTTP header, a meta tag version does nothing at all — browsers only honour the real header. The modern replacement is the Content-Security-Policy directive frame-ancestors, which accepts a list of permitted origins, for example frame-ancestors 'self' https://notion.so, and so expresses everything X-Frame-Options can plus per-origin allowances. Where both are present, browsers that support frame-ancestors follow it and ignore the older header, so the usual advice is to send both and keep them consistent.
Real-World Example
An agency publishes a signed-off proposal at northgate-proposal.99helpers.site and wants it readable only at its own address. Sending X-Frame-Options with DENY means a competitor cannot wrap it in their own page and present it as their work. A month later the same agency publishes an interactive chart meant to sit inside a client's wiki, leaves the header off that file, and adds frame-ancestors listing just the client's domain instead.
Common Mistakes
- ✕Using ALLOW-FROM to permit one partner site — no current browser honours it, so the page is either fully framed or not framed at all
- ✕Putting the header in a meta tag inside the HTML — it is only read as an HTTP response header
- ✕Setting DENY site-wide and then wondering why an embed on a partner page renders blank — the embedding side cannot override it
- ✕Sending X-Frame-Options and a conflicting frame-ancestors list, which leaves behaviour depending on which the browser prefers
Related Terms
Clickjacking
An attack in which one site loads another site's page invisibly on top of its own, so a visitor who thinks they are clicking one thing actually clicks something on the hidden page. It is defended against with headers, not with JavaScript.
Content Security Policy
A response header that tells the browser which sources a page is allowed to load scripts, styles, images and frames from. Anything outside the policy is blocked before it runs.
Security Header
An HTTP response header that instructs the browser to enforce a restriction on a page — what it may load, who may frame it, how much of its URL leaks. The server states the rule; the browser applies it.
iframe Embed
An iframe embed places another web page or file inside a rectangle on your page, as a separate document with its own address. It is the usual way to show a hosted PDF, map or demo in place.
Hotlinking
Hotlinking is when another site embeds a file using its address on your host, so every visitor to their page downloads it from you. They get the image; you get the traffic bill.
Put a file online in seconds
Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.
Host a file free →