Skip to content
Sign in
Apps SDKWidget host simulatorMenu

Widget host simulatorPro

A host on your desk for building ChatGPT Apps and MCP Apps widgets: theme, locale, display mode, max height, screen width, tool input and output editors, widget state, and a log of every call the widget makes.

ProA booking widget in a simulated host with theme, locale, screen, mode, max height, JSON editors and a call log.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/widget-host-simulator

Usage

tsx
import { WidgetHostSimulator } from "@/components/ui/chatcn/pro/widget-host-simulator"

<WidgetHostSimulator
  title="Tables"
  defaultToolOutput={fixture}
  onCallTool={(name, args) => api.call(name, args)}
>
  <BookingWidget />
</WidgetHostSimulator>

Widgets read their host through useWidgetHost() from use-chatcn-pro-host: displayMode, requestDisplayMode, maxHeight, safeArea, theme, locale, dir, toolInput, toolOutput, widgetState and the calls callTool, sendFollowUp, setWidgetState and openExternal. The contract mirrors the Apps SDK window.openai globals, so a widget built against it ports to ChatGPT Apps or MCP Apps by swapping the provider.

The simulated screen renders a short conversation with your widget inside WidgetDisplayModes, so all four modes, the docked composer and the PiP safe area behave as they would in a host. Locales that read right to left flip the screen's direction. Edits to the JSON apply after a short pause; invalid JSON keeps the last good value and names the line and column to fix.

Every call lands in the log with its payload, result or error and how long it took. sendFollowUp also appends the message to the conversation. Return or throw from onCallTool to test success and failure paths.

Examples

Errors, RTL and dark

ProEvery booking call fails with a real message, on a German screen in the dark theme.

Props

PropTypeNotes
childrenReactNodeThe widget under test
title, iconReactNodeWidget header
prompt, replystringThe conversation around the widget
defaultTheme"light" | "dark"Defaults to the page theme
defaultLocale, localesstring, { value, label }[]Six locales by default, Arabic among them
defaultDisplayMode, modesWidgetDisplayModeAll four modes by default
defaultMaxHeightnumberDefault 480, 200 to 800
defaultDevice"phone" | "tablet" | "desktop"390 px, 768 px or the full width
viewportHeightnumberDefault 680
defaultToolInput, defaultToolOutput, defaultWidgetStateunknownStarting data
onCallTool(name, args) => unknownResolve or throw. Default resolves { ok: true }
onEvent(event: WidgetHostEvent) => voidEvery call once it settles

Keyboard

KeyAction
Tab in a JSON editorIndents two spaces. Press Escape first to leave with Tab
Enter on a log rowExpands its payload and result

Accessibility

  • The call log is a log region. Each row says Done, Failed or Pending in words next to its icon.
  • JSON status lines are polite live regions that name the line and column of an error.

Motion

  • The simulator itself does not animate. Mode changes use the display mode transitions.