Perfect iframe React component

Here’s a cool iframe component that loads fast and is accessible.

If the iframe content is a small HTML demo you control, the isolated Gatsby demo approach shows a simpler srcdoc setup.

I’m thinking the iframe (Inline Frame) should have the following things:

  • Accessible: easy, because iframes have no major accessibility issues.
  • Optional caption: iframes can also be wrapped in figure.
  • Lazy loaded: for page speed, easily done with loading='lazy'.
  • Fluid width: for responsive layouts.

The React component

For simplicity this component is styled with react style object.

import type { ComponentProps } from 'react'
 
interface IframeProps extends ComponentProps<'iframe'> {
  caption?: string
  title: string
}
 
export function Iframe({
  caption,
  loading = 'lazy',
  style,
  title,
  width,
  ...props
}: IframeProps) {
  return (
    <figure
      style={{
        margin: '0 0 20px 0',
        ...(width
          ? { width }
          : {
              display: 'flex',
              flexDirection: 'column',
              overflow: 'hidden',
              width: '100%',
            }),
      }}
    >
      <iframe
        {...props}
        loading={loading}
        title={title}
        style={{
          border: '1px solid gray',
          flexGrow: 1,
          marginBottom: caption ? '3px' : '5px',
          padding: 0,
          ...style,
        }}
      />
      {!!caption && (
        <figcaption style={{ margin: 0, fontSize: '85%' }}>
          {caption}
        </figcaption>
      )}
    </figure>
  )
}

Accessibility

Iframes have no big accessibility issues in general, just remember to provide the title.

...descriptive title attribute value is not required for accessibility, but if the inline frame presents content as a whole that is visually distinctive, such as an advertisement or video player, then a title should be provided to indicate this distinction.

WebAIM

Demo

Usage:

<Iframe
  caption='This website’s 404 page loaded into an iframe'
  height={520}
  sandbox={false}
  src='https://intternet.dev/404'
  title='404 page example'
/>

Results:

This website’s 404 page loaded into an iframe

Conclusions

Remember not embed dodgy sites, same way you wouldn’t provide a link to a dodgy site. If iframes are used for same-origin URLs, there’s not much to worry about.

You should prevent other sites embedding you site into an iframe, to prevent clickjacking etc. It can be done by setting the X-Frame-Options header value to DENY.