Frame
Used to render a component in an iframe
Usage
The Frame component is used to render a component in an iframe.
- Tracks the size of the content and exposes them via css variables.
- Support for headprop to inject scripts and styles.
- Support for mount and unmount callbacks.
import { Frame } from '@ark-ui/react'
Examples
Basic
Wrap your component in the Frame component to render it in an iframe.
import { Frame } from '@ark-ui/react/frame'
export const Basic = () => {
  return (
    <Frame
      title="Custom Frame"
      style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }}
      head={<style>{'body { background-color: #f0f0f0; }'}</style>}
    >
      <div style={{ padding: '40px' }}>
        <h1>Hello from inside the frame!</h1>
        <p>This content is rendered within our custom frame component using a Portal.</p>
      </div>
    </Frame>
  )
}
import { Frame } from '@ark-ui/solid/frame'
export const Basic = () => {
  return (
    <Frame
      title="Custom Frame"
      style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }}
      head={<style>{'body { background-color: #f0f0f0; }'}</style>}
    >
      <div style={{ padding: '40px' }}>
        <h1>Hello from inside the frame!</h1>
        <p>This content is rendered within our custom frame component using a Portal.</p>
      </div>
    </Frame>
  )
}
<script lang="ts" setup>
import { Frame } from '@ark-ui/vue/frame'
</script>
<template>
  <Frame
    title="Custom Frame"
    :style="{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }"
  >
    <div style="padding: 40px">
      <h1>Hello from inside the frame!</h1>
      <p>This content is rendered within our custom frame component using a Portal.</p>
    </div>
    <template #head>
      <component is="style">body { background-color: #f0f0f0; }</component>
    </template>
  </Frame>
</template>
Injecting Script
Using the onMount prop, you can inject a script into the iframe.
import { Frame } from '@ark-ui/react/frame'
import { useRef } from 'react'
export const Script = () => {
  const ref = useRef<HTMLIFrameElement>(null)
  return (
    <Frame
      ref={ref}
      title="Custom Frame"
      onMount={() => {
        const doc = ref.current?.contentDocument
        if (!doc) return
        const script = doc.createElement('script')
        script.innerHTML = 'console.log("Hello from inside the frame!")'
        doc.body.appendChild(script)
      }}
      style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }}
    >
      <div style={{ padding: '40px' }}>
        <h1>Hello from inside the frame!</h1>
        <p>This content is rendered within our custom frame component using a Portal.</p>
      </div>
    </Frame>
  )
}
import { Frame } from '@ark-ui/solid/frame'
export const Script = () => {
  let ref: HTMLIFrameElement | undefined
  return (
    <Frame
      ref={ref}
      title="Custom Frame"
      onMount={() => {
        const doc = ref?.contentDocument
        if (!doc) return
        const script = doc.createElement('script')
        script.innerHTML = 'console.log("Hello from inside the frame!")'
        doc.body.appendChild(script)
      }}
      style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }}
    >
      <div style={{ padding: '40px' }}>
        <h1>Hello from inside the frame!</h1>
        <p>This content is rendered within our custom frame component using a Portal.</p>
      </div>
    </Frame>
  )
}
<script setup lang="ts">
// biome-ignore lint/style/useImportType: <explanation>
import { Frame } from '@ark-ui/vue/frame'
import { ref } from 'vue'
const frameRef = ref<InstanceType<typeof Frame> | null>(null)
const onMount = () => {
  const doc = frameRef.value?.frameRef?.contentDocument
  if (!doc) return
  const script = doc.createElement('script')
  script.innerHTML = 'console.log("Hello from inside the frame!")'
  doc.body.appendChild(script)
}
</script>
<template>
  <Frame
    ref="frameRef"
    title="Custom Frame"
    @mount="onMount"
    :style="{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }"
  >
    <div style="padding: 40px">
      <h1>Hello from inside the frame!</h1>
      <p>This content is rendered within our custom frame component using a Portal.</p>
    </div>
  </Frame>
</template>
Custom src doc
Use the srcDoc prop to specify the HTML content of the page to use in the iframe.