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
head
prop 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'
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'
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'
</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 { useRef } from 'react'
import { Frame } from '@ark-ui/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'
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">
import { ref } from 'vue'
// biome-ignore lint/style/useImportType: <explanation>
import Frame from '@ark-ui/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.
import { Frame } from '@ark-ui/react'
const srcDoc = `<html><head>
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
<base target=_blank>
</head><body style='overflow: hidden'><div></div></body></html>`
export const SrcDoc = () => {
return (
<Frame
title="Custom Frame"
style={{ border: '1px solid #ccc', maxWidth: '800px', width: '100%' }}
srcDoc={srcDoc}
>
<h1 style={{ fontFamily: 'Open Sans, sans-serif' }}>Hello from inside the frame!</h1>
<p>This content is rendered within our custom frame component using a Portal.</p>
<p>The frame has custom initial content, including Font Awesome and Open Sans font.</p>
</Frame>
)
}
import { Frame } from '@ark-ui/solid'
const srcDoc = `<html><head>
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
<base target=_blank>
</head><body style='overflow: hidden'><div></div></body></html>`
export const SrcDoc = () => {
return (
<Frame title="Custom Frame" style={{ border: '1px solid #ccc', width: '100%' }} srcdoc={srcDoc}>
<h1 style={{ 'font-family': 'Open Sans, sans-serif' }}>Hello from inside the frame!</h1>
<p>This content is rendered within our custom frame component using a Portal.</p>
<p>The frame has custom initial content, including Font Awesome and Open Sans font.</p>
</Frame>
)
}
<script lang="ts" setup>
import Frame from '@ark-ui/vue'
const srcDoc = `<html><head>
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
<base target=_blank>
</head><body style='overflow: hidden'><div class='frame-root'></div></body></html>`
</script>
<template>
<Frame
title="Custom Frame"
:style="{ border: '1px solid #ccc', width: '100%' }"
:src-doc="srcDoc"
>
<h1 style="font-family: 'Open Sans', sans-serif">Hello from inside the frame!</h1>
<p>This content is rendered within our custom frame component using a Portal.</p>
</Frame>
</template>