# 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](/simple-demo) 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.

```tsx showLineNumbers
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](https://webaim.org/techniques/frames/)

## Demo

Usage:

```jsx
<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:

[404 page example](https://intternet.dev/404)

## 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](https://owasp.org/www-community/attacks/Clickjacking) etc. It can
be done by setting the `X-Frame-Options` header value to `DENY`.
