# HTML Viewer

An isolated iframe preview for HTML content.

Page: https://sui.draco.dev/docs/components/html-viewer

### Example: html-viewer-demo

```tsx
"use client";
import { HtmlViewer } from "@workspace/ui/components/html-viewer";
import type { ExampleProps } from "../types";
export default function Example({ locale }: ExampleProps) {
  const chinese = locale === "zh-CN";
  const content = `<!doctype html><html lang="${chinese ? "zh-CN" : "en-US"}"><head><meta charset="utf-8"><style>body{font:14px system-ui;margin:24px;color:#202020;background:#f5f5f7}button{font:inherit;padding:8px 12px;border:1px solid #ccc;border-radius:12px;background:white}p{line-height:1.6}</style></head><body><h2>${chinese ? "隔离的 HTML 预览" : "Isolated HTML preview"}</h2><p>${chinese ? "此按钮仅改变 iframe 内的文字" : "This button changes text only inside the iframe."}</p><button onclick="this.textContent='${chinese ? "脚本已运行" : "Script ran"}'">${chinese ? "测试沙箱脚本" : "Test sandboxed script"}</button></body></html>`;
  return (
    <HtmlViewer
      content={content}
      title={chinese ? "交互式 HTML 示例" : "Interactive HTML example"}
      className="h-64 w-full rounded-xl border"
    />
  );
}
```

## Installation

```bash
bunx --bun shadcn@latest add @sui/html-viewer
```

Install with the shadcn CLI or use the shared `@workspace/ui` package. Follow the [installation guide](/docs/installation) to configure the registry, load styles, and choose import aliases.

## Usage

```tsx
import { HtmlViewer } from "@workspace/ui/components/html-viewer";

<HtmlViewer
  content="<h2>Hello</h2><p>Isolated HTML content.</p>"
  title="HTML content preview"
  className="h-64 w-full rounded-xl border"
/>;
```

## Iframe isolation

The component writes `content` to the iframe `srcDoc`. Styles inside the HTML document do not affect the surrounding application, and the application theme is not automatically injected into the document. Include the document styles you want to preview. Give the iframe a descriptive `title`, or translate `labels.preview`.

The default sandbox is `"allow-scripts"`, permitting scripts inside an opaque-origin frame without granting `allow-same-origin`. The first example demonstrates a button that changes only the iframe content.

## Restricting scripts

Set `sandbox=""` for a static preview without script execution. Pass other native iframe attributes, such as `allow`, `loading`, and `ref`, when needed. Changing sandbox permissions changes the capabilities of the content; keep permissions limited to what your preview requires.

### Example: html-viewer-sandbox

```tsx
"use client";
import { HtmlViewer } from "@workspace/ui/components/html-viewer";
import { Label } from "@workspace/ui/components/label";
import { Textarea } from "@workspace/ui/components/textarea";
import { useId, useState } from "react";
import type { ExampleProps } from "../types";
export default function Example({ locale }: ExampleProps) {
  const chinese = locale === "zh-CN";
  const id = useId();
  const [content, setContent] = useState(
    chinese
      ? "<h2>静态 HTML</h2><p>没有脚本权限的预览。</p>"
      : "<h2>Static HTML</h2><p>A preview without script permission.</p>",
  );
  return (
    <div className="grid w-full gap-3">
      <Label htmlFor={id}>{chinese ? "HTML 源码" : "HTML source"}</Label>
      <Textarea
        id={id}
        value={content}
        onChange={(event) => setContent(event.target.value)}
        rows={3}
      />
      <HtmlViewer
        content={content}
        sandbox=""
        title={
          chinese
            ? "禁止脚本的 HTML 预览"
            : "HTML preview with scripts disabled"
        }
        className="h-48 w-full rounded-xl border"
      />
    </div>
  );
}
```

## Layout and glass

The iframe defaults to filling its container. Set an explicit height on the component or its parent. `glass` styles the outer surface; it does not refract, capture, or theme the separate iframe document. Glass background snapshots cannot reliably include iframe contents.

## API reference

| Prop | Type | Default / behavior |
| --- | --- | --- |
| `content` | `string` | Required HTML source; mapped to `srcDoc`. |
| `sandbox` | Native iframe sandbox | `"allow-scripts"`. |
| `title` | `string` | `labels.preview` or `"HTML preview"`. |
| `labels` | `{ preview?: string }` | Fallback accessible title. |
| `glass` | `boolean` | `false`. |
| Other props | Native iframe props | Forwarded, including `className`, `ref`, and `loading`. |

The module exports `HtmlViewerProps`. See the [iframe element documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) for sandbox permissions. For source editing with preview, use [Editor](/docs/components/editor).
