browser-preview
Preview panel and iframe diagnostics: registry, ports, paths, blank screens. Use when a preview tab is broken or missing (e.g. white screen, tab disappeared, 404 on assets, preview not loading, list running services).
By starchild-ai-agent · 4,581 installs
npx skills add starchild-ai-agent/official-skills --skill browser-preview
Source repository · Upstream listing
Browser Preview
You already know preview serve and preview stop . This skill fills the gap: what happens after preview serve returns a URL — how the user actually sees it.
What is the Preview Panel
The frontend has a right side panel with two tabs: Files and Preview . The Preview tab renders preview URLs inside an iframe. When you call preview serve , the frontend automatically opens a Preview tab loading that URL. (Jobs are now managed in a standalone modal accessible from the left sidebar, not in the right panel.)
Key facts:
Each preview serve call creates one Preview tab
URL format: https://<host /preview/{id}/
Preview panel has a ⋮ menu (top right) showing "RUNNING SERVICES" list
Preview tab can be closed by the user without stopping the backend service
Backend service stopping → Preview tab shows an error page
⚠️ CRITICAL: Never Tell Users to Access localhost
The user's browser CANNOT access localhost or 127.0.0.1 . These addresses point to the server container, not the user's machine. The preview architecture uses a reverse proxy :
Rules:
NEVER tell the user to visit http://localhost:{port} or http://127.0.0.1:{port} — they cannot reach it
ALWAYS direct users to the preview URL: /preview/{id}/ (or the full URL https://<host /preview/{id}/ )
curl http://localhost:{port} is for your own server side diagnostics only — never suggest it to the user as a way to "test" the preview
When a preview is running, tell the user: "Check the Preview panel, or refresh the Preview panel"
If you need to give the user a URL, use the url field returned by preview serve (format: /preview/{id}/ )
⚠️ Static Assets Must Use Relative Paths
Because previews are served under /preview/{id}/ , absolute paths in HTML/JS/CSS will break . The reverse proxy strips the /preview/{id} prefix before forwarding to the backend, but the browser resolves absolute paths from the domain root.
Example of the problem:
Common patterns to fix:
Broken (absolute) Fixed (relative)
"/static/app.js" "static/app.js" or "./static/app.js"
"/api/users" "api/users" or "./api/users"
"/images/logo.png" "images/logo.png" or "./images/logo.png"
url('/fonts/x.woff') url('./fonts/x.woff')
fetch('/data.json') fetch('data.json')
Check ALL places where paths appear:
1. HTML src , href attributes
2. JavaScript fetch() , XMLHttpRequest , dynamic imports
3. CSS url() references
4. JavaScript string literals (e.g., '/static/' in template strings or concatenation)
5. Framework config files (e.g., publicPath , base , assetPrefix )
⚠️ Be thorough — it's common to fix CSS url() but miss JS string literals like '/static/' (with single quotes). Search for ALL occurrences of absolute paths across all file types.
⚠️ Do NOT Browse Filesystem to Debug Previews
Never look at workspace directories like preview/ , output/ , or random folders to understand preview state. Those are user data, not preview service state.
The only sources of truth:
1. Registry file: /data/previews.json (running services)
2. History file: /data/preview history.json (all past services)
3. preview serve / preview stop tools
4. Port checks via curl (server side only, for your diagnostics)
Do NOT use ls / find on workspace directories to diagnose preview issues. Do NOT call unrelated tools like list scheduled tasks . Stay focused.
Step by Step: Diagnosing Preview Issues
When a user reports any Preview panel problem, follow this exact sequence:
Step 1: Read the registry (running services)
⚠️ Your bash CWD is /data/workspace/ . The registry is at /data/previews.json (absolute path, one level up). Always use the absolute path.
JSON structure:
Step 2: Branch based on registry state
If registry has entries → Go to Step 3 (verify services)
If registry is empty or missing → Go to Step 4 (check history)
Step 3: Registry has entries — verify and fix
For each preview in the registry, check if the port is responding server side (this is your diagnostic, not for the user):
If port responds (200):
The service IS running. Tell the user:
"You have a running service: {title}"
"Click the ⋮ menu at the top right of the Preview panel, then click it in the RUNNING SERVICES list to reopen"
Preview URL: /preview/{id}/
If user says the ⋮ menu is empty or doesn't show the service → frontend lost sync. Fix by recreating: preview stop(id) then preview serve(dir, title, command) using the info from the registry. This forces the frontend to re register the tab.
If port does NOT respond:
Process crashed but registry entry remains. Recreate:
Step 4: No running services — check history first, then scan workspace
When there are no running services, use a two tier lookup to find projects the user can preview:
Tier 1: Read preview history (preferred — fast and accurate)
JSON structure:
History entries are never removed by preview stop — they persist across restarts. Entries are automatically pruned only when the project directory no longer exists.
If history has entries:
List all history entries to the user with title, directory, and last started time
Ask which one they want to restart
Call preview serve with the dir , title , and command from the history entry
If user says a project is missing from history → fall through to Tier 2.
Tier 2: Scan workspace (fallback — when history is empty or incomplete)
Then:
1. List discovered projects with brief descriptions
2. Ask the user which one to preview
3. Call preview serve with the appropriate directory
Don't just say "no services running" and stop. Always check history first, then scan, and offer options.
Quick Reference
User says You do
"tab disappeared" / "tab 不见了" Step 1 → 2 → 3 or 4
"blank page" / "白屏" Check port (server side), if dead → recreate; if alive → check for absolute path issues
"not updating" / "内容没更新" Suggest refresh button in Preview tab, or recreate preview
"port conflict" / "端口冲突" preview stop old → preview serve new
"can't see service" / "⋮ menu empty" preview stop + preview serve to force re register
"where's my project" / "what did I build" Read /data/preview history.json and list entries
"resource load failed" / "JS/CSS 404" Check for absolute paths ( /static/ , /api/ ), fix to relative paths
What You Cannot Do
Cannot directly open/close/refresh Preview tabs (frontend UI)
Cannot force refresh the iframe
Cannot read what the iframe displays
When you can't do something, tell the user the manual action (e.g., "click refresh in Preview tab"). If manual action doesn't work, recreate the preview with preview stop + preview serve .
Common Mistakes to Avoid
1. ❌ Telling user to "visit http://localhost:18791/" — user cannot access localhost
2. ❌ Saying "refresh the page at localhost" — meaningless to the user
3. ❌ Only fixing CSS url() paths but missing JS string literals with absolute paths
4. ❌ Forgetting to check ALL file types (HTML, JS, CSS, config) for absolute paths
5. ✅ Always use /preview/{id}/ as the user facing URL
6. ✅ Always use curl localhost:{port} only for your own server side diagnostics
7. ✅ After fixing paths, call preview stop + preview serve to restart, then tell user to check Preview panel