Skip to content
WorkspaceWeb previewMenu

Web preview

An iframe preview for apps an agent builds: URL bar with history, device sizes, a browser style loading bar, a crash view and a console drawer.

Navigate a running app: links, history, loading, a crash and the console.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/web-preview.json

Usage

tsx
import { WebPreview } from "@/components/ui/chatcn/web-preview"

<WebPreview
  url={url}
  onUrlChange={setUrl}
  logs={logs}
  error={crash ? { message: crash } : null}
  onRetry={restartDevServer}
  className="h-[560px]"
/>

Enter in the URL bar navigates and adds a history entry; back, forward and reload work like a browser tab. Bare hosts get a scheme: localhost:3000 becomes http://localhost:3000. Pass srcDoc to show HTML you generate, or resolveSrc to route URLs through a sandbox proxy.

Console messages come in as logs. To capture them from a page you control, forward console calls with postMessage, as the demo does; cross-origin frames cannot be read directly.

Examples

Error and console

A crashed page with the console open on the stack.

Device sizes

Tablet and mobile keep their logical width (768 and 390 px by default) and scale down to fit with a transform, so the page lays out exactly as on the device. The size and scale show under the frame.

The mobile frame keeps its logical width and scales to fit.

Props

PropTypeNotes
url, defaultUrl, onUrlChangestringControlled or uncontrolled
srcDocstringHTML to show instead of loading the URL
resolveSrc(url) => stringMap a URL to the iframe src
loadingbooleanOverride. Defaults to the iframe load event
progressnumber0 to 1 for a determinate bar
error, onRetry{ title?, message? } | stringCrash view. Retry reloads by default
device, defaultDevice, onDeviceChange"desktop" | "tablet" | "mobile"
deviceWidths{ tablet?, mobile? }Logical widths
logsWebPreviewLog[]level, message, timestamp?, source?
consoleOpen, defaultConsoleOpen, onConsoleOpenChangeboolean
onClearLogs() => voidShows Clear
sandboxstringAdd allow-same-origin only for URLs on another origin than your app
actionsReactNodeExtra toolbar buttons
emptyStateReactNodeShown with no URL

Keyboard

KeyAction
Enter in the URL barNavigate. Ignored while an IME is composing
Esc in the URL barRestore the current URL
TabBack, forward, reload, URL, devices, open in new tab, console

Accessibility

  • Device sizes are a radio group. Icon buttons have names and tooltips.
  • The crash view is an alert with a real Retry button. The console is a labelled region with a log list, and each message says its level.
  • Error counts on the console button pair an icon with the number and a hidden word.

Motion

  • The 2 px loading bar waits 150 ms before showing, trickles toward 90%, completes, holds for the 400 ms minimum and fades.
  • Switching device settles the frame with scale 0.97 to 1 and opacity over 280 ms, never a width tween.
  • The console slides up 220 ms and down 160 ms. Reduced motion keeps the fades only.