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 height leads 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

PropTypeRequiredNotes
srcstringyesURL of content to embed
titlestringyesAccessible name for assistive tech
widthstring | numbernoInitial width (e.g., '100%')
heightstring | numbernoInitial fallback height
responsiveOptionsResponsiveOptionsnoConfiguration (see below)
hideUntilResizedbooleannoHide iframe until first resize event
onResized(dims: {width:number;height:number}) => voidnoCalled on each resize
onMessage(evt: MessageEvent) => voidnoListen to custom messages from iframe
onInit() => voidnoCalled when handshake completes
allowstringnoStandard iframe allow policy
sandboxstringnoE.g., allow-scripts allow-same-origin
referrerPolicystringnoE.g., strict-origin-when-cross-origin
loading'lazy' | 'eager'noNative lazy loading
classNamestringnoClass for outer container
styleReact.CSSPropertiesnoInline 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.

Links