Build responsive, auto‑resizing iframes in React with react-responsive-iframe
react-responsive-iframe is a lightweight, TypeScript‑ready React component (plus a hook) that automatically resizes an iframe to fit its content. It’s designed for smooth, responsive embeds without layout jumps, with a secure message handshake and flexible configuration.
If you’ve ever dropped an iframe into a page and watched it overflow or jump once it loads, this is for you.
Why standard iframes cause problems
- Fixed
heightleads to huge whitespace or scrollbars. - Dynamic content (expanding accordions, async data) breaks initial sizing.
- Without coordination, you either poll for size or accept layout shifts.
Install
npm i react-responsive-iframe
or:
yarn add react-responsive-iframe
Quick start
import { ResponsiveIframe } from 'react-responsive-iframe'
export default function Demo() {
return (
<ResponsiveIframe
src="https://example.com/embedded"
title="Embedded app"
width="100%"
height={300} // fallback initial height
responsiveOptions={{
autoResize: true,
heightCalculationMethod: 'bodyScroll',
minHeight: 200,
}}
hideUntilResized
onResized={(dims) => {
console.log('Iframe resized:', dims) // { width, height }
}}
/>
)
}
What it does
- Sets up a secure, event‑based handshake between the parent page and the iframe.
- Automatically adjusts the iframe’s height (and optionally width) to match content.
- Avoids continuous polling; resizes when content changes.
- Lets you hide the iframe until the first correct size is known to prevent jumps.
API
| Prop | Type | Required | Notes |
|---|---|---|---|
src | string | yes | URL of content to embed |
title | string | yes | Accessible name for assistive tech |
width | string | number | no | Initial width (e.g., '100%') |
height | string | number | no | Initial fallback height |
responsiveOptions | ResponsiveOptions | no | Configuration (see below) |
hideUntilResized | boolean | no | Hide iframe until first resize event |
onResized | (dims: {width:number;height:number}) => void | no | Called on each resize |
onMessage | (evt: MessageEvent) => void | no | Listen to custom messages from iframe |
onInit | () => void | no | Called when handshake completes |
allow | string | no | Standard iframe allow policy |
sandbox | string | no | E.g., allow-scripts allow-same-origin |
referrerPolicy | string | no | E.g., strict-origin-when-cross-origin |
loading | 'lazy' | 'eager' | no | Native lazy loading |
className | string | no | Class for outer container |
style | React.CSSProperties | no | Inline styles for outer container |
Tip: Always provide a meaningful
title, like “Product walkthrough video”.
ResponsiveOptions
type ResponsiveOptions = {
heightCalculationMethod?:
| 'bodyScroll'
| 'documentElementOffset'
| 'scrollHeight'
widthCalculationMethod?: 'scrollWidth' | 'offsetWidth'
tolerance?: number // px before resize triggers
autoResize?: boolean // default: true
checkOrigin?: boolean // default: true
minHeight?: number
maxHeight?: number
minWidth?: number
maxWidth?: number
}
Examples
Basic, full‑width embed
<ResponsiveIframe
src="https://example.com/embedded"
title="Embedded app"
width="100%"
height={300}
responsiveOptions={{
autoResize: true,
heightCalculationMethod: 'bodyScroll',
}}
hideUntilResized
/>
Prevent initial jump
<ResponsiveIframe
src="https://example.com/long-content"
title="Long content"
width="100%"
responsiveOptions={{ minHeight: 300, autoResize: true }}
hideUntilResized
/>
Inside the iframe (optional)
If you control the embedded page and it’s built with React, you can send resize messages using the provided hook:
import { useIframeResizer } from 'react-responsive-iframe'
export default function IframeContent() {
const { resize, isInitialized } = useIframeResizer({
heightCalculationMethod: 'bodyScroll',
autoResize: true,
})
// Call resize() after content changes if autoResize is disabled,
// or when you know height changed significantly.
return (
<div>
<p>Status: {isInitialized ? 'Ready' : 'Connecting…'}</p>
{/* ... */}
</div>
)
}
FAQ
Does it work with Next.js (App Router)?
Yes. Use it in client components where you render embeds.
What happens if the embedded site is cross‑origin and I don’t control it?
Auto‑resize still works if the content sends size messages. If not, you can provide a reasonable fallback height and let users scroll.
Do I need to set an initial height?
It’s optional but recommended as a fallback before the first resize event.