Skip to main content

Dev Preview Tools

What you can do inside a Dev Preview panel: navigation and the toolbar, device emulation and viewport presets, find in page, and the Output, Console and Diagnostics drawer including DevTools.

Updated
Reviewed

Toolbar

The shared browser controls:

  • Back / Forward: move through page history (disabled when there's no history in that direction)
  • Reload: refresh the current page. Shift+click does a hard reload that ignores the cache
  • Zoom out / zoom level / zoom in: click the percentage label to reset to 100%. Presets run 25%, 50%, 75%, 100%, 125%, 150%, 200%
  • Address bar: shows the current URL on the proxy origin. Edit it and press Enter to navigate. Frecency-based autocomplete suggests URLs from your history as you type
  • Copy URL: copies the current URL to the clipboard
  • Screenshot (camera icon): captures the visible page and copies it to the clipboard as a PNG. Disabled until the webview is ready, and skipped on blank pages
  • Console (terminal icon): opens the drawer on the Console tab
  • DevTools (code icon): opens Chromium DevTools for the previewed page in a detached window. Disabled until the webview is ready
  • Open in Portal: promotes the current page into a Portal tab that shares this panel's session
  • Open in Browser: opens the page through a short-lived proxy bootstrap in your default browser. Application logins are separate from the embedded browser. See Opening the page in your real browser

Command-R Control-R Control-R reloads the focused dev preview without touching the server process.

Note
Screenshots go to the clipboard, not a file. Capture the page, then paste it straight into an issue, a chat, or a notes app.

Device emulation

Dev Preview emulates real mobile devices, not just their user agent. Turn on a preset and you get full Chromium device emulation: a real mobile viewport, the correct window.devicePixelRatio, proper viewport-meta handling, touch and pointer media features (pointer: coarse, hover: none), and mobile scrollbars. Swapping only navigator.userAgent would leave layouts looking like a narrow desktop window rather than a phone.

Click the viewport toggle (smartphone icon) in the toolbar to turn emulation on. A row of preset chips appears, each carrying the matching device dimensions and user-agent string:

PresetViewport (portrait)
Galaxy S26360 × 780
iPhone 17393 × 852
Pixel 10412 × 923
iPad Air 11"820 × 1180

With a preset active, the page renders inside a rounded, bordered device frame, centered in the pane. Three more controls fine-tune it:

  • Rotate: swaps width and height to switch between portrait and landscape
  • Device pixel ratio: a 1× / 2× / 3× selector (default 1×) that sets the device scale factor, so high-DPR assets and srcset selection behave the way they would on the real device
  • Zoom to fit: scales the device frame down to fit the pane
Tip
Zoom to fit never upscales. It caps at 100%, so a small viewport stays at its real device size instead of stretching to fill the pane. Touch targets and type stay at a realistic scale rather than blurring up.

Preset, rotation, DPR and zoom are per-panel state that Daintree remembers. There is nothing to configure in Settings for device emulation.

Find in page

Press Command-F Control-F Control-F to search the current page. A floating find bar appears in the top-right of the webview with a text input, a match counter, a Match case (Aa) toggle, and previous/next buttons. It searches as you type and shows the current position ("3 / 12"), or "No results". The shortcut works whether the Daintree UI or the embedded page has focus; pressing it again while the bar is open refocuses and selects the input.

The find bar is the same component the Browser panel uses, and the shortcut table there applies here too.

Output, Console and Diagnostics

The drawer at the bottom of the panel toggles from the Output drawer button, whose chevron shows the open/closed state. It has three tabs:

  • Output: your dev server's terminal output, the same stream you would see if you ran the command yourself
  • Console: the previewed page's browser console, with a red badge carrying the current error count
  • Diagnostics: the session's lifecycle timeline and its current proxy state

A color-coded dot in the drawer header reports the server's state:

StateIndicatorMeaning
StoppedGreyServer not running
Stopped (restored)GreyThe server was running when Daintree last closed. Nothing was reattached; restart to run it again
StartingAmberProcess launched, waiting for the ready signal
InstallingAmberMissing packages detected; dependencies are being installed
RunningGreenServer is up and serving
StoppingAmberShutting the server process down
ErrorRedServer failed to start or crashed

While a restart is underway the header shows a Restarting label in amber.

Stop and restart

A Stop button sits in the drawer header whenever the server is starting, installing, running or stopping, and is disabled while a restart is already in flight. Stopping doesn't clear your configured command, so the panel shows a Waiting for dev server placeholder rather than falling back to the setup prompt.

Restart is a split button. Clicking the main part restarts the dev server; the chevron opens a menu with four options:

  • Reload preview: reloads the page without touching the server process
  • Restart dev server: kills the server process and relaunches it
  • Restart and clear cache: relaunches after deleting framework build caches (.next, .vite, .turbo, .svelte-kit, .astro, .nuxt and node_modules/.vite)
  • Reinstall dependencies: relaunches after deleting node_modules and reinstalling

The last two ask for confirmation first and are disabled mid-install. The preview names the workspace, affected directories and detected package manager; size checks may still be pending or unavailable. Daintree stops the server and waits for its port to become free before removing those paths. These operations delete directory contents by their configured cache/dependency names, so keep hand-authored work out of those directories. Reinstall runs the detected package manager’s install command; Git history is not a deletion target.

Warning
Restarting clears the terminal logs that explain what went wrong. When a start is stuck or a crash is unexplained, read the Output tab before you restart, or check the Diagnostics tab afterwards: the timeline survives the restart even though the logs do not.

Console tab

The Console tab captures the previewed page's browser console through the Chrome DevTools Protocol: the same messages DevTools would show, structured rather than flattened to text:

  • Level filters: All, Errors, Warn, and Log (Log includes info). Errors and Warn carry counts
  • Text filter: narrows messages by content
  • Message detail: a level badge (LOG / INF / WRN / ERR), a timestamp, an object inspector for logged objects, stack traces, and collapsible console groups
  • Clear: empties the captured log

Capture holds roughly the last 500 messages per panel, survives switching tabs, and is cleared when the panel is deleted. Messages from a previous page are dimmed rather than dropped after a navigation.

Note
The Console tab shows the previewed page's console (your app's console.log calls and runtime errors). The Output tab shows the dev server's terminal output (build steps, compile errors, request logs). When something is wrong, check both. Console capture is specific to Dev Preview: Browser panels do not have it.

Diagnostics tab

Diagnostics answers "what just happened?" without asking you to reconstruct it from logs. The top of the tab is a summary: status, allocated port, detected URL, what the proxy would dial right now, the proxy's own port (and whether it fell back off 43000), and crash-loop state. Below it is the lifecycle timeline, newest first: ensure requested, config changed, port allocated, spawned, install started and finished, URL detected, readiness probe result, compile started and finished, restart and stop requests, process exits, crash-loop backoff, and proxy failures. Errors are tinted; repeated identical events carry a ×N count.

Each session keeps its last 100 events, and Daintree retains rings for the 50 most recently touched sessions, so a timeline outlives the panel that produced it. Free-text detail is capped at 200 characters, and identical consecutive proxy failures inside a 10-second window coalesce into one counted row, so a retrying webview can't flush the lifecycle history that explains it.

A proxy 502 always names its cause:

CauseWhat it means
No session registered for this originThe origin isn't bound to a dev-preview panel, usually a stale tab or a page reopened after the panel was closed
Dev server isn't runningThe panel exists but its server is stopped, starting, or errored
Dev server refused the connectionThe port is not accepting connections, typically the server died or hasn't bound yet
Dev server timed outThe upstream accepted the connection but never answered within 30 seconds
Dev server connection failedAnything else, with the underlying error code attached

WebSocket upgrade failures are recorded the same way, which is what usually explains a preview that renders but never live-reloads.

The proxy dials the URL the server reported, not the port Daintree allocated for it