# How to Insert an Iframe into a React Component Using react-iframe

> Learn to insert an iframe into your React component with the react-iframe package. This type-safe wrapper efficiently integrates iframes using React's DOM component logic.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-14

---

**Use the `react-iframe` npm package to render a type-safe wrapper that passes props directly to the native `<iframe>` host element, leveraging React’s internal DOM component logic in [`ReactDOMComponent.js`](https://github.com/facebook/react/blob/main/ReactDOMComponent.js).**

The `facebook/react` repository treats iframes as standard **host components**, meaning they follow the same reconciliation path as other HTML elements. While you can insert a native `<iframe>` tag directly in JSX, the `react-iframe` library provides built-in TypeScript definitions, ref forwarding, and security defaults that simplify embedding external content.

## How React Renders Iframe Elements Internally

React processes any lowercase HTML tag as a host component. When JSX encounters `<iframe …/>`, the reconciler creates a `ReactDOMComponent` with `type` set to the string `"iframe"` and forwards props to the native DOM element.

This logic resides in **[`packages/react-dom-bindings/src/client/ReactDOMComponent.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactDOMComponent.js)**, specifically around **line 1366** where the `case 'iframe'` branch registers the element and validates its attributes, and again at **line 3119** for attribute updates.

Because iframes create a **nested browsing context**, React implements special handling for mouse events. The test suite in **[`packages/react-dom/src/events/plugins/__tests__/EnterLeaveEventPlugin-test.js`](https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/__tests__/EnterLeaveEventPlugin-test.js)** (lines 38–78) verifies that `relatedTarget` for enter/leave events correctly references the iframe’s `contentWindow`.

## Why Use the react-iframe Package?

The `react-iframe` package is a thin wrapper around the native element that does not alter React’s rendering path. It returns a JSX element of type `"iframe"` with your supplied props, letting React’s core pipeline handle the actual DOM manipulation.

**Key advantages over native `<iframe>`:**

- **Prop-type validation**: Built-in TypeScript and PropTypes support for `url`, `width`, `height`, and event handlers
- **Default sandbox**: Automatically sets `sandbox="allow-scripts allow-same-origin"` unless overridden
- **Ref forwarding**: Exposes `iframeRef` for direct DOM access without manual ref handling
- **Convenience API**: Simplified props like `allow` and `position` map directly to HTML attributes

## Implementing Iframes in React Components

### Basic Usage with react-iframe

Import the component and provide the target URL along with dimension constraints:

```tsx
import Iframe from 'react-iframe';

function SimpleIframe() {
  return (
    <Iframe 
      url="https://www.example.com" 
      width="100%" 
      height="400px" 
      id="example-iframe" 
      display="initial" 
      position="relative" 
      allow="camera; microphone" 
      sandbox="allow-scripts allow-same-origin" 
      onLoad={() => console.log('iframe loaded')} 
    />
  );
}

```

*The component renders a native `<iframe>`; all props map 1-to-1 to the underlying element.*

### Accessing the Iframe Ref for Same-Origin Content

To manipulate the iframe’s document directly, use the `ref` prop to obtain the DOM node. This only works for **same-origin** content due to browser security policies:

```tsx
import { useRef, useEffect } from 'react';
import Iframe from 'react-iframe';

export default function RefIframe() {
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    const iframe = iframeRef.current;
    if (iframe?.contentDocument) {
      const doc = iframe.contentDocument;
      // Example: inject a simple style
      const style = doc.createElement('style');
      style.textContent = 'body { background: #f0f0f0; }';
      doc.head.appendChild(style);
    }
  }, []);

  return (
    <Iframe 
      url="https://same-origin.example.com" 
      ref={iframeRef} 
      width="100%" 
      height="500px" 
      sandbox="allow-scripts allow-same-origin" 
    />
  );
}

```

**Note:** Accessing `contentDocument` or `contentWindow` throws a security error for cross-origin iframes. React’s internal `isSameOriginFrame` helper in **[`packages/react-dom-bindings/src/client/ReactInputSelection.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactInputSelection.js)** (line 43) performs similar checks for text selection logic.

### TypeScript Support and Type Definitions

The package exports interfaces for prop autocompletion:

```ts
interface IframeProps {
  url: string;
  width?: string | number;
  height?: string | number;
  id?: string;
  className?: string;
  display?: string;
  position?: string;
  allow?: string;
  sandbox?: string;
  loading?: 'eager' | 'lazy';
  onLoad?: () => void;
}

```

Import typings directly:

```ts
import Iframe, { IframeProps } from 'react-iframe';

```

### Lazy Loading and Browser Fallbacks

Modern browsers support the `loading="lazy"` attribute to defer off-screen iframe loading. For older browsers, use a ref callback to polyfill:

```tsx
<Iframe 
  url="https://www.example.com" 
  width="100%" 
  height="400px" 
  loading="lazy" 
  sandbox="allow-scripts allow-same-origin"
  ref={el => {
    if (el && !('loading' in HTMLIFrameElement.prototype)) {
      el.setAttribute('loading', 'lazy');
    }
  }} 
/>

```

## Security Best Practices for React Iframes

When you insert an iframe into a React component, follow these guidelines to prevent XSS and performance issues:

1. **Always set a sandbox attribute** – Restrict permissions with `sandbox="allow-scripts"` or stricter values unless you require full access.
2. **Validate same-origin access** – Check `iframe.contentDocument` availability before interacting with the DOM; cross-origin frames return `null` per the Same-Origin Policy.
3. **Enable lazy loading** – Use `loading="lazy"` to prevent blocking the main thread with off-screen iframes.
4. **Specify explicit dimensions** – Define `width` and `height` to avoid **Cumulative Layout Shift (CLS)** during rendering.

## Key Source Files in the React Repository

Understanding React’s iframe implementation requires examining these specific files:

- **[`packages/react-dom-bindings/src/client/ReactDOMComponent.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactDOMComponent.js)** – Contains the `case 'iframe'` switch logic at lines 1366 and 3119 that handles prop validation and attribute mapping.
- **[`packages/react-dom/src/__tests__/ReactDOMIframe-test.js`](https://github.com/facebook/react/blob/main/packages/react-dom/src/__tests__/ReactDOMIframe-test.js)** – Unit tests verifying iframe rendering lifecycle and `onLoad` behavior.
- **[`packages/react-dom/src/events/plugins/__tests__/EnterLeaveEventPlugin-test.js`](https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/__tests__/EnterLeaveEventPlugin-test.js)** – Tests mouse event propagation across iframe boundaries (lines 38–78).
- **[`packages/react-dom-bindings/src/client/ReactInputSelection.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactInputSelection.js)** – Implements `isSameOriginFrame` helper (line 43) used for iframe text selection security checks.

## Summary

- React treats `<iframe>` as a host component processed by [`ReactDOMComponent.js`](https://github.com/facebook/react/blob/main/ReactDOMComponent.js), forwarding props directly to the native DOM element.
- The `react-iframe` package provides a type-safe wrapper with sensible defaults like sandbox restrictions and ref forwarding without altering React’s internal rendering pipeline.
- Accessing iframe content requires same-origin policies; use `contentDocument` only when the URL matches your domain.
- Always implement sandbox attributes, lazy loading, and explicit sizing to ensure security and performance.

## Frequently Asked Questions

### Can I use a native `<iframe>` tag instead of react-iframe?

Yes. React supports native `<iframe>` tags directly in JSX, routing them through the same `ReactDOMComponent` logic in [`packages/react-dom-bindings/src/client/ReactDOMComponent.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactDOMComponent.js). However, `react-iframe` adds TypeScript definitions, automatic ref forwarding, and default sandbox attributes that reduce boilerplate and improve type safety.

### Why does accessing iframe.contentDocument return null?

Browsers implement the **Same-Origin Policy** to prevent cross-site scripting. If the iframe `src` points to a different domain, protocol, or port than your React application, `contentDocument` and `contentWindow` return `null` and any access attempt throws a security error. This restriction is enforced at the browser level, not by React.

### How do I communicate between a React parent component and an iframe?

For same-origin iframes, use the `ref` to access `contentWindow` and call `postMessage` or directly manipulate the DOM. For cross-origin communication, use the standard `window.postMessage` API with target origin validation. The `react-iframe` package forwards the `onLoad` callback, which is the safest point to begin message passing once the iframe document has initialized.

### Does react-iframe support server-side rendering (SSR)?

The `react-iframe` component renders a standard `<iframe>` element that React hydrates on the client. Since iframes create separate browsing contexts that cannot be meaningfully serialized to HTML without executing their source content, they are typically rendered only on the client or handled as pass-through elements during SSR hydration. Ensure your `url` prop is available during the initial render to avoid hydration mismatches.