Application Preview
Relevant source files
The following files were used as context for generating this wiki page:
The Application Preview system provides a real-time, in-browser viewing environment for full-stack web applications generated within the platform. By leveraging the WebContainer API, the system can detect active network ports, map them to accessible URLs, and render the resulting application within a sandboxed iframe. This allows users to iterate on code and immediately see the results without leaving the browser tab.
Sources: README.md:12-25, app/components/workbench/Preview.tsx:1-125
System Architecture
The preview system is built on a reactive architecture using nanostores for state management. It bridges the gap between the low-level WebContainer events and the React-based UI components.
Core Components
| Component | Responsibility |
|---|---|
PreviewsStore | Listens to WebContainer 'port' events and maintains a list of active preview URLs. |
WorkbenchStore | Orchestrates the high-level view state, including whether the workbench is showing "code" or "preview". |
Preview.tsx | The primary UI container that renders the address bar, reload controls, and the application iframe. |
PortDropdown.tsx | A specialized selector used when multiple ports (e.g., frontend and backend) are active simultaneously. |
Sources: app/lib/stores/previews.ts:1-45, app/lib/stores/workbench.ts:24-45, app/components/workbench/Preview.tsx:7-15
Data Flow and Event Mapping
The system reacts to lifecycle events from the underlying WebContainer. When a process starts a server on a specific port, the WebContainer emits an event that the PreviewsStore captures to update the global state.
The diagram shows how port events from the WebContainer trigger state updates that ultimately refresh the Iframe source.
Sources: app/lib/stores/previews.ts:23-43, app/components/workbench/Preview.tsx:18-28
Preview State Management
The PreviewsStore class is the central authority for active network ports. It tracks PreviewInfo objects, which contain the port number, its ready state, and the base URL provided by the WebContainer environment.
Preview Selection Logic
When multiple ports are available, the system defaults to the lowest port number unless the user explicitly selects a different one. This is handled by a reduction function within the UI layer.
This sequence illustrates the automatic selection of the lowest active port upon a new service starting.
Sources: app/lib/stores/previews.ts:12-44, app/components/workbench/Preview.tsx:55-68
User Interface and Controls
The Preview UI mimics a standard web browser interface, providing tools for navigation and environment management.
Address Bar and Validation
The address bar allows users to see the current URL and manually navigate within the sub-paths of the preview. It includes validation logic to ensure the user stays within the authorized base URL provided by the container.
- Base URL Match: Users can navigate to the exact base URL.
- Sub-path Validation: Navigation is permitted if the URL starts with the base URL followed by a path separator (
/), query (?), or fragment (#).
Sources: app/components/workbench/Preview.tsx:39-53, app/components/workbench/Preview.tsx:86-108
Port Selection (Multi-port Support)
If an application runs multiple services (e.g., a Vite frontend on port 5173 and an API on port 3001), the PortDropdown component appears. It sorts available ports in ascending order and allows the user to switch the iframe source between them.
| Data Field | Type | Description |
|---|---|---|
port | number | The network port number (e.g., 3000). |
ready | boolean | Indicates if the port is currently open and accepting traffic. |
baseUrl | string | The external URL mapped to the internal container port. |
Sources: app/lib/stores/previews.ts:4-8, app/components/workbench/PortDropdown.tsx:15-30
Integration with Workbench
The preview system is a first-class view within the Workbench.client.tsx. The workbench automatically switches the view from 'code' to 'preview' as soon as a port becomes active.
Technical Implementation Details
Reload Logic
Reloading the preview is implemented by re-assigning the iframe's src attribute to itself, forcing the browser to refresh the sandboxed content.
const reloadPreview = () => {
if (iframeRef.current) {
iframeRef.current.src = iframeRef.current.src;
}
};
Sources: app/components/workbench/Preview.tsx:70-74
External Change Syncing
The system includes mechanisms to synchronize changes between the preview environment and the editor. While the preview renders the running state, the WorkbenchStore periodically checks for file system changes and syncs them to the editor store to ensure the preview and the code remain consistent.
Sources: app/lib/stores/workbench.ts:133-146
The Application Preview feature provides a seamless bridge between code generation and execution, utilizing a reactive store architecture to handle dynamic network environments within WebContainers.