> For the complete documentation index, see [llms.txt](https://docs.customiframe.com/llms.txt).
> Use it to discover all available pages before exploring further.

# Embed Blocked or Refused

Understand why an embed is blocked in Custom iFrame and how to fix it. Covers X-Frame-Options, Content-Security-Policy, and how to extract the correct embed URL.


## Overview

When an embed is blocked, the browser refuses to display the external URL inside an iframe. This is not a plugin error. The embedded site sends HTTP response headers that instruct the browser to block the frame. This guide explains what those headers mean, how to identify them, and what you can do.

## How to Confirm the Embed Is Blocked

<Steps>
  <Step title="Open the page with the embed" icon="layout" title-type="p">
    Go to the page where the iFrame shows blank or refuses to load.
  </Step>
  <Step title="Open browser DevTools" icon="terminal" title-type="p">
    Press **F12** (Windows/Linux) or **Cmd + Option + I** (Mac). Go to the **Console** tab.
  </Step>
  <Step title="Look for a frame error" icon="search" title-type="p">
    Reload the page. A blocked embed shows one of these errors:

    ```
    Refused to display 'https://example.com' in a frame because it set
    'X-Frame-Options' to 'sameorigin'.
    ```

    ```
    Refused to frame 'https://example.com' because an ancestor violates
    the following Content Security Policy directive: "frame-ancestors 'self'"
    ```

    If you see either of these, the embedded site is blocking the iframe.
  </Step>
</Steps>

---

## Why Embeds Get Blocked

### X-Frame-Options Header

`X-Frame-Options` is an HTTP response header. The embedded server sends it along with the page content. The browser reads it and decides whether to display the page in a frame.

| Header value | What it means |
|---|---|
| `X-Frame-Options: DENY` | The page cannot be displayed in any iframe, on any site |
| `X-Frame-Options: SAMEORIGIN` | The page can only be embedded on pages from the same domain |
| `X-Frame-Options: ALLOW-FROM uri` | The page allows embedding only from the specified URI (deprecated, ignored by most modern browsers) |

### Content-Security-Policy: frame-ancestors

`Content-Security-Policy` is the modern replacement for `X-Frame-Options`. The `frame-ancestors` directive controls which origins can embed the page.

| Directive | What it means |
|---|---|
| `frame-ancestors 'none'` | No site can embed this page in an iframe |
| `frame-ancestors 'self'` | Only the same origin can embed this page |
| `frame-ancestors https://trusted.com` | Only the specified domain can embed this page |

Both headers are set by the embedded site. You cannot override them from your WordPress site, from the Custom iFrame plugin, or from the browser.

---

## The Fix: Use the Embed src URL Instead of the Page URL

Many platforms that restrict their regular page URL still offer a separate **embed URL** designed specifically for iframe use. This embed URL is served from a player or embed endpoint without restrictive headers.

The platform provides this URL as part of their **iframe embed code**.

<Steps>
  <Step title="Find the embed code on the platform" icon="code" title-type="p">
    On the platform where your content lives, look for a **Share**, **Embed**, or **Get embed code** option. The location varies by platform:

    - **YouTube:** Click Share below the video, then click Embed
    - **Vimeo:** Click Share, then click the Embed tab
    - **Spotify:** Click the three-dot menu on a track, then Share, then Embed
    - **Google Maps:** Click Share, then Embed a map
    - **Google Calendar:** Go to calendar Settings, then Integrate calendar
    - **Facebook posts:** Click the three-dot menu on a post, then Embed
    - **LinkedIn posts:** Click the three-dot menu, then Embed this post
  </Step>
  <Step title="Copy the embed code" icon="clipboard" title-type="p">
    The platform gives you an HTML snippet. It looks like this:

    ```html
    <iframe src="https://player.vimeo.com/video/76979871?h=abc123"
      width="640" height="360" frameborder="0"
      allow="autoplay; fullscreen" allowfullscreen>
    </iframe>
    ```
  </Step>
  <Step title="Extract only the URL from the src attribute" icon="link" title-type="p">
    Copy the URL value from `src="..."`. For the example above, that is:

    ```
    https://player.vimeo.com/video/76979871?h=abc123
    ```

    Do not copy the full HTML tag. Copy only the URL between the quotation marks.
  </Step>
  <Step title="Paste the src URL into Custom iFrame" icon="paste" title-type="p">
    In Elementor or Gutenberg, paste that URL into the **Source URL** field in the Custom iFrame widget or block. Save and publish.
  </Step>
</Steps>

<Callout kind="success">
  The embed src URL is the URL the platform designed for iframe use. It does not carry the same X-Frame-Options or CSP restrictions as the regular page URL.
</Callout>

---

## Sites That Block Embedding

Some platforms block their regular page URLs from being embedded. Where they provide an embed code, use the src URL from that code.

| Platform | Regular URL embeddable? | Embed code available? |
|---|---|---|
| YouTube | Yes (use youtube.com/embed/... format) | Yes |
| Vimeo | Yes (page URL works) | Yes |
| Spotify | No (open.spotify.com blocks) | Yes — use embed URL |
| Google Maps | No (maps.google.com blocks) | Yes — use embed URL |
| Google Calendar | No | Yes — use embed URL |
| Facebook pages | No | No |
| Facebook posts | No (post page blocks) | Yes — use plugin URL |
| Instagram posts | No | Yes — use embed URL |
| LinkedIn posts | No | Yes — use embed URL |
| Twitter / X posts | No — uses script-based embeds | No iframe src available |
| Google Search | No | No |
| Most banking sites | No | No |

<Callout kind="alert">
  Twitter/X uses JavaScript-based embeds, not iframe src URLs. There is no src URL to extract. The Custom iFrame plugin handles X posts using its built-in X source type.
</Callout>

---

## What to Do If There Is No Embed Code

If the platform does not provide an iframe embed code and its page URL is blocked, the content cannot be embedded in an iframe. This is a restriction enforced by the platform, not by Custom iFrame or WordPress.

Options in this situation:
- Link to the content on the platform instead of embedding it
- Take a screenshot and link it to the source URL
- Use the platform's official sharing widget if one is available (these are script-based, not iframe-based)

---

## FAQ

<ExpandableGroup>
  <Expandable title="Can I bypass X-Frame-Options with a proxy or redirect?" default-open="false">
    A server-side proxy that fetches and re-serves the content from your domain would technically bypass the header, because the browser sees your domain as the source. However, this approach involves caching third-party content on your server, which raises significant legal, copyright, and performance concerns. It is outside the scope of Custom iFrame.
  </Expandable>
  <Expandable title="The platform's embed code uses JavaScript, not an iframe. Can Custom iFrame handle that?" default-open="false">
    No. Custom iFrame uses the HTML iframe element. It requires a URL to embed. Script-based embeds (like Twitter/X, Pinterest, and some Spotify widgets) cannot be pasted as a URL. For Twitter/X posts, use Custom iFrame's built-in X source type, which handles the rendering differently.
  </Expandable>
  <Expandable title="The embed src URL worked before but stopped working. Why?" default-open="false">
    Platforms sometimes update their embed URLs. The URL may have expired (some platforms add time-limited tokens to embed URLs), or the platform changed its embed endpoint. Go back to the platform, regenerate the embed code, and extract the new src URL.
  </Expandable>
  <Expandable title="How do I find X-Frame-Options in the Network tab?" default-open="false">
    Open DevTools, go to the **Network** tab, reload the page, click the request for the embedded URL, and look at the **Response Headers** section. If `x-frame-options` or `content-security-policy` appears there, check its value.
  </Expandable>
</ExpandableGroup>

---

## Related Guides

- [iFrame Not Showing](/troubleshooting/iframe-not-showing)
- [iFrame Height Fix](/troubleshooting/iframe-height-fix)
- [Sandbox and Security in Gutenberg](/gutenberg/advanced/iframe-sandbox-security)
