Fix a Dev Preview
What to do when a Dev Preview does not work: no server found, the command exits, no URL detected, a port conflict, a blank page, and navigation Daintree blocked on purpose.
When it goes wrong
Slow or stuck startup
Daintree waits for the dev server to respond before showing the preview. The wait window is configurable from 1 to 120 seconds (default 30) in Project Settings. Daintree does not restart a slow server on its own; it escalates in stages so you can decide:
- After 6 seconds: an ambient working indicator on the panel. No banner
- After 20 seconds: a warning banner ("Dev server is slow to start") with a Restart dev server button, noting that restarting clears the logs you may want to read first. Suppressed if the server has reported that it is compiling: a compile is a signal, not a stall
- After 45 seconds: an error banner. If the server logged a recognizable error, the banner shows it and offers the matching remedy (Restart and clear cache, or Reinstall dependencies) with a plain restart in the overflow. Otherwise it names the likely causes: the port is still bound, dependencies are missing, or the build cache is stuck. If the server is still compiling, the copy switches to "First compile is taking longer than usual" instead
The timers reset the moment the server leaves the Starting state, and the Installing state suppresses them, so a long first-run install doesn't trigger a false warning.
Crash loops
A broken configuration (missing dependencies that an install can't fix) would otherwise drive an unbounded install-crash-reinstall cycle that burns CPU and battery. A guard counts consecutive fast crashes and backs off geometrically between attempts, starting at 500ms, multiplying by 1.5, capped at 3 seconds. After 5 attempts it stops respawning and leaves the session in a recoverable stopped state you can restart by hand. A server that stays up for 5 seconds graduates and resets the counter, so fixing the bug is not punished by a long wait. Every step is recorded in the Diagnostics timeline.
Live reload has silently died
A custom server.hmr.* config can point Vite's browser socket somewhere that isn't reachable from the proxy origin. The dev server keeps logging [vite] hmr update on every save (which reads as "live reload is working") while the page never updates. Daintree matches Vite's own HMR failure messages in the console stream and raises a Live reload disconnected banner with a Reload button, so a stale preview is visible rather than confusing.
Certificate and connection errors
A failed page load replaces the preview with a named error rather than a blank pane: "Certificate error", "Dev server unreachable", "Dev server unavailable", "Page load timed out", "Couldn't resolve address". A certificate error adds a Copy mkcert -install button, which is the fix nearly every time a local HTTPS dev server fails to be trusted. Connection-refused and proxy errors offer Restart dev server with the full restart menu behind it.
On a plain connection-refused or connection-reset, Daintree first retries up to 5 times with exponential backoff from 500ms up to 8 seconds, showing "Reconnecting (attempt N of 5)". That covers the common race where the dev server announces itself as ready a moment before it is actually reachable.
The page crashed or stopped responding
If the preview's renderer process dies, a Preview process crashed banner names the reason and exit code and offers Reload, with Hard restart in the overflow. If the page stops responding (usually a long-running script), a Preview is not responding banner appears with the same hard-restart escape. Both are dismissible.
Blocked external navigation
If a page in the preview navigates to a different origin from your dev server, Daintree intercepts it and shows a banner: Navigation blocked: [domain], using the registrable domain (example.com, not the full hostname). From the banner you can Copy URL or Open in External Browser, which dismisses it.
OAuth sign-in
When the blocked URL looks like an OAuth flow, the banner offers Sign in via browser instead. That runs a loopback sign-in: Daintree intercepts the token exchange and completes the sign-in back in the embedded page, so you stay in the preview rather than ending up signed in only in a separate browser session. The flow moves through an intercepting state (with Cancel) and then completes ("Sign in completed"), times out ("Sign in didn't complete"), or errors ("Couldn't start sign-in") with Try again.