Web Preview

PreviousNext

A flexible component to preview web content with integrated console for debugging.

"use client"

import { useState } from "react"
import { ChevronLeftIcon, ChevronRightIcon, RotateCwIcon } from "lucide-react"

import {
  WebPreview,
  WebPreviewBody,
  WebPreviewConsole,
  WebPreviewNavigation,
  WebPreviewNavigationButton,
  WebPreviewUrl,
} from "@/components/ai-elements/web-preview"

export function WebPreviewDemo() {
  const [url, setUrl] = useState("https://ai-sdk.dev")
  const [logs] = useState([
    {
      level: "log" as const,
      message: "Page loaded successfully",
      timestamp: new Date(),
    },
    {
      level: "log" as const,
      message: "Ready to display content",
      timestamp: new Date(),
    },
  ])

  return (
    <div className="h-[600px] w-full">
      <WebPreview defaultUrl={url} onUrlChange={setUrl}>
        <WebPreviewNavigation>
          <WebPreviewNavigationButton disabled tooltip="Back">
            <ChevronLeftIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewNavigationButton disabled tooltip="Forward">
            <ChevronRightIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewNavigationButton tooltip="Refresh">
            <RotateCwIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewUrl placeholder="Enter URL..." />
        </WebPreviewNavigation>

        <WebPreviewBody src={url} />

        <WebPreviewConsole logs={logs} />
      </WebPreview>
    </div>
  )
}

Installation

pnpm dlx shadcn@latest add web-preview

Usage

import {
  WebPreview,
  WebPreviewNavigation,
  WebPreviewNavigationButton,
  WebPreviewUrl,
  WebPreviewBody,
  WebPreviewConsole,
} from "@/components/ai-elements/web-preview"
const [url, setUrl] = useState("https://example.com")
 
<WebPreview defaultUrl={url} onUrlChange={setUrl}>
  <WebPreviewNavigation>
    <WebPreviewNavigationButton tooltip="Back">
      <ChevronLeftIcon />
    </WebPreviewNavigationButton>
    <WebPreviewNavigationButton tooltip="Forward">
      <ChevronRightIcon />
    </WebPreviewNavigationButton>
    <WebPreviewNavigationButton tooltip="Refresh">
      <RotateCwIcon />
    </WebPreviewNavigationButton>
    <WebPreviewUrl placeholder="Enter URL..." />
  </WebPreviewNavigation>
 
  <WebPreviewBody src={url} />
 
  <WebPreviewConsole logs={[]} />
</WebPreview>

Examples

Default

"use client"

import { useState } from "react"
import { ChevronLeftIcon, ChevronRightIcon, RotateCwIcon } from "lucide-react"

import {
  WebPreview,
  WebPreviewBody,
  WebPreviewConsole,
  WebPreviewNavigation,
  WebPreviewNavigationButton,
  WebPreviewUrl,
} from "@/components/ai-elements/web-preview"

export function WebPreviewDemo() {
  const [url, setUrl] = useState("https://ai-sdk.dev")
  const [logs] = useState([
    {
      level: "log" as const,
      message: "Page loaded successfully",
      timestamp: new Date(),
    },
    {
      level: "log" as const,
      message: "Ready to display content",
      timestamp: new Date(),
    },
  ])

  return (
    <div className="h-[600px] w-full">
      <WebPreview defaultUrl={url} onUrlChange={setUrl}>
        <WebPreviewNavigation>
          <WebPreviewNavigationButton disabled tooltip="Back">
            <ChevronLeftIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewNavigationButton disabled tooltip="Forward">
            <ChevronRightIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewNavigationButton tooltip="Refresh">
            <RotateCwIcon className="size-4" />
          </WebPreviewNavigationButton>
          <WebPreviewUrl placeholder="Enter URL..." />
        </WebPreviewNavigation>

        <WebPreviewBody src={url} />

        <WebPreviewConsole logs={logs} />
      </WebPreview>
    </div>
  )
}

Anatomy

The WebPreview component is composed of several sub-components:

<WebPreview>
  <WebPreviewNavigation>
    <WebPreviewNavigationButton />
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody />
  <WebPreviewConsole />
</WebPreview>

Features

  • Live Preview: Display web content in an iframe with sandbox protection
  • URL Navigation: Input field for entering URLs with Enter key support
  • Navigation Controls: Back, forward, and refresh buttons with tooltip support
  • Integrated Console: Collapsible console panel for logging and debugging
  • Context Management: Shared state between components via React Context
  • Responsive Design: Adapts to different screen sizes and layouts
  • Keyboard Support: Press Enter in URL input to navigate
  • Sandbox Security: iframe includes security restrictions for safe preview

API Reference

WebPreview

Main container that provides context for all child components.

PropTypeDefaultDescription
defaultUrlstring""Initial URL to load
onUrlChange(url: string) => void-Callback when URL changes
classNamestring-Custom CSS classes

WebPreviewNavigation

Navigation bar that contains controls and URL input.

PropTypeDefaultDescription
classNamestring-Custom CSS classes
childrenReactNode-Navigation controls

WebPreviewNavigationButton

Button for navigation actions (back, forward, refresh, etc.).

PropTypeDefaultDescription
tooltipstring-Tooltip text on hover
disabledbooleanfalseDisable the button
onClick() => void-Click handler
childrenReactNode-Button content (usually an icon)

WebPreviewUrl

URL input field with automatic syncing to preview context.

PropTypeDefaultDescription
placeholderstring"Enter URL..."Placeholder text
valuestring-Controlled value (optional)
onChange(e: ChangeEvent) => void-Change handler (optional)
onKeyDown(e: KeyboardEvent) => void-Key down handler (optional)

The URL input automatically syncs with the preview context. Press Enter to navigate to the entered URL.

WebPreviewBody

iframe container for displaying web content.

PropTypeDefaultDescription
srcstring-URL to display (overrides context URL)
loadingReactNode-Loading indicator overlay
classNamestring-Custom CSS classes

The iframe includes sandbox restrictions: allow-scripts allow-same-origin allow-forms allow-popups allow-presentation

WebPreviewConsole

Collapsible console panel for displaying logs.

PropTypeDefaultDescription
logsArray<ConsoleLog>[]Array of console log entries
classNamestring-Custom CSS classes
childrenReactNode-Additional console content

ConsoleLog Type:

{
  level: "log" | "warn" | "error"
  message: string
  timestamp: Date
}

The console displays with color coding:

  • log: Default foreground color
  • warn: Yellow
  • error: Destructive color

Advanced Usage

With Loading State

<WebPreview defaultUrl={url}>
  <WebPreviewNavigation>
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody
    src={url}
    loading={
      isLoading && (
        <div className="absolute inset-0 flex items-center justify-center bg-background/80">
          <Loader />
        </div>
      )
    }
  />
</WebPreview>

With Console Logging

const [logs, setLogs] = useState<Array<ConsoleLog>>([])
 
// Add logs from your app
const addLog = (level: "log" | "warn" | "error", message: string) => {
  setLogs(prev => [...prev, { level, message, timestamp: new Date() }])
}
 
<WebPreview defaultUrl={url}>
  <WebPreviewNavigation>
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody src={url} />
  <WebPreviewConsole logs={logs} />
</WebPreview>

Custom Navigation Controls

<WebPreview defaultUrl={url}>
  <WebPreviewNavigation>
    <WebPreviewNavigationButton
      onClick={() => console.log('Back')}
      tooltip="Go back"
    >
      <ChevronLeftIcon className="size-4" />
    </WebPreviewNavigationButton>
    <WebPreviewNavigationButton
      onClick={() => console.log('Forward')}
      tooltip="Go forward"
    >
      <ChevronRightIcon className="size-4" />
    </WebPreviewNavigationButton>
    <WebPreviewNavigationButton
      onClick={() => window.location.reload()}
      tooltip="Refresh"
    >
      <RotateCwIcon className="size-4" />
    </WebPreviewNavigationButton>
    <WebPreviewUrl />
  </WebPreviewNavigation>
  <WebPreviewBody src={url} />
</WebPreview>

Hooks

useWebPreview

Access the preview context from within child components (not exported by default).

const { url, setUrl, consoleOpen, setConsoleOpen } = useWebPreview()

This hook is used internally by the sub-components and is not typically needed in user code.