KDS
Code

WebPreview

iframe-based preview de site/app gerado pelo modelo — barra de URL, console, navigation.

Overview

WebPreview renderiza um site/app dentro de iframe com chrome de browser — URL bar, navigation buttons, optional console output. Usado pra preview live de UI gerada por IA (v0, lovable-style), ou pra mostrar referências externas em surface controlada.

Preview
Preview de site dentro de iframe com URL bar.

Anatomy

<WebPreview defaultUrl onUrlChange>
  ├─ <WebPreviewNavigation>
  │    ├─ <WebPreviewNavigationButton tooltip>...
  │    └─ <WebPreviewUrl />
  ├─ <WebPreviewBody />              ← iframe
  └─ <WebPreviewConsole logs />       ← opcional
</WebPreview>

Usage

<WebPreview defaultUrl="https://ds.kalvner.com">
  <WebPreviewNavigation>
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody />
</WebPreview>

Props

WebPreview (Root)

PropTipoDefaultDescrição
defaultUrlstringURL inicial (uncontrolled).
onUrlChange(url: string) => voidCallback ao mudar URL no input.

Aceita ComponentProps<"div">. Provider interno que segura a URL atual.

WebPreviewNavigation

Aceita ComponentProps<"div">. Wrapper flex pros buttons + URL bar.

WebPreviewNavigationButton

PropTipoDefaultDescrição
tooltipstringTooltip do botão (envolve em Tooltip).

Herda de Button. Default variant="ghost" size="icon".

WebPreviewUrl

Herda de Input. Lê do contexto e atualiza ao Enter.

WebPreviewBody

Herda de iframe. Aceita src (override do contexto), sandbox, loading, etc.

PropTipoDefaultDescrição
srcstringOverride (lê do contexto se não passado).
loading'eager' | 'lazy'Loading hint.
sandboxstring'allow-scripts allow-same-origin'Iframe sandbox.

WebPreviewConsole

PropTipoDefaultDescrição
logsArray<{ level, message, timestamp }>[]Logs do console capturados.

Aceita ComponentProps<"div">. Mostra logs com cores baseadas em level.

Subcomponents

  • WebPreview — root + provider de URL atual.
  • WebPreviewNavigation — barra de navegação flex.
  • WebPreviewNavigationButton — botão genérico (Refresh, Open in new tab).
  • WebPreviewUrl — Input de URL (Enter dispara navigate).
  • WebPreviewBody — iframe.
  • WebPreviewConsole — terminal de logs.

States

EstadoVisual
Loadingiframe mostra fallback browser.
Console openWebPreviewConsole renderiza abaixo do body.
Console closedBody ocupa todo o espaço.

Composition

v0-style — preview + chat

<div className="grid grid-cols-[1fr_440px]">
  <WebPreview defaultUrl={generatedUrl}>
    <WebPreviewNavigation>
      <WebPreviewNavigationButton tooltip="Refresh">
        <RefreshCw />
      </WebPreviewNavigationButton>
      <WebPreviewUrl />
      <WebPreviewNavigationButton tooltip="Open">
        <ExternalLink />
      </WebPreviewNavigationButton>
    </WebPreviewNavigation>
    <WebPreviewBody />
  </WebPreview>
  <Conversation>...</Conversation>
</div>

Com console capturado

<WebPreview defaultUrl="https://app.example/preview">
  <WebPreviewNavigation>
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody className="flex-1" />
  <WebPreviewConsole
    logs={[
      { level: "log", message: "Hot reload connected", timestamp: new Date() },
      { level: "warn", message: "Deprecated API", timestamp: new Date() },
      { level: "error", message: "Failed to fetch", timestamp: new Date() }
    ]}
  />
</WebPreview>

When to use

  • Preview de site gerado por IA (v0, lovable, bolt).
  • Sandbox de testes (codesandbox-style).
  • Preview de URL externa em context controlado.

When not to use

  • Snippet de código sem run — use CodeBlock.
  • Imagem renderizada — use Image.
  • Conteúdo same-origin que pode ir inline — sem iframe.

Best practices

  • Sandbox restritivo. sandbox="allow-scripts allow-same-origin" é o mínimo. Evite allow-top-navigation em iframes não confiáveis.
  • CSP friendly. Verifique se o iframe target permite ser embedado (X-Frame-Options).
  • Console opcional. Só mostre console quando ajuda debug — sem isso, polui o preview.

Accessibility

ConcernComportamento
iframeAdicione title no <WebPreviewBody> — leitor de tela usa pra contexto.
URL inputAcessível via Tab + Enter.
ConsoleLogs precisam de <time> semântico pra timestamps lerem corretamente.

On this page