Preview Modes
frame.mode is the switch that gates isolation entirely — every other
frame option below is inert until it's set. Without mode, Live.Preview
renders straight into the host document, regardless of any other frame
options passed.
iframe— isolates the preview in a real iframe document. Note this is not a security sandbox: the code still executes in the host page's JS realm (thesandboxoption below controls the iframe'ssandboxattribute, which is DOM/CSS isolation, not a security boundary either). Supports every option in the table below.shadow— isolates styles via a shadow DOM host in the same document, without an iframe boundary.scripts,styles,stylesheets, andautoHeightare all silently ignored, since there's no separate document to inject them into. The shadow host only gets whatever CSS naturally inherits across the shadow boundary (font, color, and similar inherited properties) on its own — not utility classes. Two ways to get those working too:syncStyleclones the host document's<link>/<style>tags directly into the shadow root (covers anything already in the host's compiled CSS, including a consuming app's own custom theme tokens), anddynamicTailwindrecompiles whatever classes it finds in the rendered DOM at runtime (covers anything the host's build never saw, e.g. a class typed at runtime) — see How Tailwind reaches the preview. The two are complementary and can be used together.
import Live from '@jbpark/live-editor';
const SAMPLE = `
import * as ui from 'ui-kit';
const App = () => (
<div className="p-6 space-y-2">
<ui.Typography.Title level={4}>Preview Modes</ui.Typography.Title>
<ui.Button type="primary">A button</ui.Button>
</div>
);
export default App;
`;
export default function PreviewModes() {
return (
<>
{/* iframe isolation */}
<Live>
<Live.Preview
code={SAMPLE}
dynamicTailwind
frame={{ mode: 'iframe', syncStyle: true }}
/>
</Live>
{/* shadow DOM isolation */}
<Live>
<Live.Preview
code={SAMPLE}
dynamicTailwind
frame={{ mode: 'shadow', syncStyle: true }}
/>
</Live>
</>
);
}
Unlike the other demos on this site, this one is rendered directly in the page — not inside a sandboxed iframe — since it has no reader-authored code to isolate (the sample is a fixed string, not wired to an editor).
frame options
FrameProps (importable from @jbpark/live-editor) is this shape:
| Option | Type | Applies to | Description |
|---|---|---|---|
mode | 'iframe' | 'shadow' | both | Isolation strategy. Omit it and nothing else in this table has any effect. |
title | string | iframe | The iframe's title attribute (accessibility). |
sandbox | string | iframe | Forwarded to the iframe's sandbox attribute, for DOM/CSS isolation only — not a security boundary (see the note above). |
syncStyle | boolean | both | Copy the host document's already-compiled <link>/<style> tags in (into the iframe document, or directly into the shadow root). Can't include utility classes that only appear in code typed at runtime — see How Tailwind reaches the preview. |
scripts | string[] | iframe | External script URLs to load into the iframe document (e.g. a Tailwind runtime). |
styles | string[] | iframe | Raw CSS strings to inject as <style> tags into the iframe. |
stylesheets | string[] | iframe | External stylesheet URLs to <link> into the iframe. |
autoHeight | boolean | iframe | Size the iframe to its content instead of a fixed height. |
onLoaded | () => void | iframe | Called once the iframe has finished its initial load. |