ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-04-26Intermediate

Why Antigravity's Browser Preview Goes Blank — A Diagnosis Workflow That Actually Works

Your agent says the dev server is up, but Antigravity's embedded preview is blank. Here's the order of checks I run to narrow it down to the real cause in a few minutes.

antigravity429browser-previewtroubleshooting105agents123dev-server2

You ask the agent to fix a Next.js page and show you the result. The Manager Surface confirms "Started dev server on port 3000," the Walkthrough says "verify at http://localhost:3000," and yet the embedded browser inside Antigravity stays stubbornly white. Out of curiosity, you open the same URL in your real browser — and everything works fine. So what just happened?

This is one of the most common preview issues in Antigravity, and it usually traces back to one of three categories. Once I started classifying the symptom before touching any restart button, I stopped wasting cycles on the wrong fix. Below is the diagnosis order I now use whenever a preview goes blank, plus a few defaults I add to every project to keep it from happening again.

"Blank" is actually three different states

When the preview shows nothing, you're really looking at one of these three situations, and the fix for each is different.

  • HTML is delivered, but the body is empty. "View source" shows something like <html><body></body></html>. This is a build error, a JS exception, or a failed SSR/SSG pass.
  • The connection never opens. You see "Connection refused," "Failed to fetch," or an infinite spinner. The dev server isn't actually listening on the port the preview is hitting.
  • The connection works, but the iframe refuses to render. Content-Security-Policy with frame-ancestors (or X-Frame-Options: DENY) blocks the embedded browser specifically.

The fastest way to tell them apart is the "Open in external browser" button on the preview panel. Try the same URL outside the IDE.

  • Blank in the external browser too → app-side issue (pattern 1)
  • Error in the external browser → connection issue (pattern 2)
  • Works fine in the external browser → embed-side restriction (pattern 3)

This 30-second triage step alone probably saves more time than any single fix in this article.

Pattern 1 — HTML arrives, but the page is empty

If the page is blank in your real browser too, it's an app problem. Here's the order I check.

Start by scrolling all the way through the Manager Surface terminal output. Agents tend to declare success the moment they see "Started server," but Webpack or Vite often emits compile errors a second or two later. The agent does not always notice these — its own past output is one of its blind spots.

Next, open DevTools inside the preview (top-right "Inspect" button, or Cmd/Ctrl + Option + I). Watch both Console and Network. Hydration mismatches and module-load 404s are the usual suspects.

Finally, look at what the dev server is actually returning.

# See exactly what the dev server hands back
curl -s http://localhost:3000 | head -50

If you see an empty mount point like <div id="root"></div>, the server is fine and the problem is on the client/SSR side. The most reliable next step is to ask the agent explicitly: "Look back through the most recent compile errors in the terminal and fix the file that caused them." Agents forget their own errors more often than you'd expect, so an explicit prompt to re-read the log fixes the issue much faster than another vague "preview's blank, try again."

Pattern 2 — The connection never opens

When you see "Connection refused" or ERR_CONNECTION_REFUSED, run through this order.

Check the actual port. The Walkthrough may say "verify at localhost:3000," but Vite usually starts on 5173. Memorise the defaults so you don't get tripped up: Next.js 3000, Vite 5173, Remix 3000, Nuxt 3000, Astro 4321.

Check for a port collision.

# macOS / Linux — find who's holding 3000
lsof -i :3000
 
# Windows (PowerShell)
Get-NetTCPConnection -LocalPort 3000

If something else already owns the port, the dev server quietly migrates to a different one and the agent rarely updates the Walkthrough. Always confirm the actual bound port from the tail of the terminal output.

Watch out for the localhost-binding trap. Vite binds to 127.0.0.1 by default. If Antigravity's embedded browser tries to connect using a different hostname, the request gets refused. I now make this a default in every project:

// vite.config.ts
import { defineConfig } from 'vite';
 
export default defineConfig({
  server: {
    host: true,        // Bind to 0.0.0.0 so the embedded browser can reach it
    port: 5173,
    strictPort: true,  // Don't silently jump to another port if 5173 is taken
  },
});

For Next.js, the equivalent is updating the dev script in package.json to next dev -H 0.0.0.0 -p 3000. Next doesn't have a strictPort equivalent, so I pair it with a quick lsof -i :3000 before starting the agent on a new task.

Pattern 3 — The connection works but the iframe is blocked

If the URL loads fine externally but the embedded preview is blank, it's almost always Content-Security-Policy with frame-ancestors, or an X-Frame-Options: DENY header. The defaults from Express + Helmet, Cloudflare Pages, and Vercel can all produce this.

Open DevTools Console and you'll see something like:

Refused to display 'http://localhost:3000/' in a frame because an
ancestor violates the following Content Security Policy directive:
"frame-ancestors 'self'".

The fix is to relax the policy in development only. Express + Helmet example:

// server.js — relax the policy ONLY in development
import helmet from 'helmet';
 
app.use(
  helmet({
    contentSecurityPolicy:
      process.env.NODE_ENV === 'production'
        ? undefined // keep strict CSP in production
        : {
            directives: {
              'frame-ancestors': [
                "'self'",
                'http://localhost:*',
                'http://127.0.0.1:*',
              ],
            },
          },
    crossOriginEmbedderPolicy: false, // only if embedded rendering still breaks
  })
);

Never relax CSP in production builds. When I add this kind of dev-only escape hatch I leave a big // DEV ONLY comment at the top of the file so it's hard to accidentally ship.

When nothing above works

A short list of things to try when you've exhausted the patterns above:

  • Run the dev server outside the agent. Open Antigravity's terminal, run npm run dev yourself, and try the same URL in your external browser. If that works, the agent's process supervisor is the one stuck.
  • Verify your /etc/hosts file still has the localhost line. On macOS, some security tools occasionally rewrite it.
  • Disable VPN and corporate proxies temporarily. Proxies can break localhost resolution in subtle ways. The full corporate-network playbook is in our guide on fixing Antigravity behind firewalls and proxies.
  • Close and reopen the embedded browser tab. Cached state in the preview can survive a server restart.
  • Reload the workspace. When the internal preview proxy hangs, closing and reopening the project tends to clear it.

Defaults that prevent most of this

Here's what I now bake into new projects from day one to make blank-preview incidents rare.

  • Always pass -H 0.0.0.0 (or --host) in the dev script in package.json.
  • For Vite-style configs, set both server.host: true and server.strictPort: true. The strict port is what prevents the silent jump that confuses the agent.
  • Loosen frame-ancestors in development, never in production. Wrap the whole CSP block in a process.env.NODE_ENV check.
  • Add explicit guidance in AGENTS.md: "Always bind dev servers to 0.0.0.0" and "After starting any server, run lsof -i :<port> once and paste the output into the Walkthrough."

That last point matters more than it sounds. Whether the agent writes the bound port into the Walkthrough is largely a function of how clearly AGENTS.md asks for it. Without an explicit rule, the agent often quotes the requested port even when the server actually moved.

Closing thought

When the preview goes blank, the single biggest time-saver is the 30-second test in the external browser. It tells you which of the three patterns you're in before you change a single line of code. The smallest concrete step you can take today is to add -H 0.0.0.0 to your dev script and commit it — the next time this happens, you'll already have eliminated an entire category of causes.

If your Walkthrough panel is also blank or stale, that's a different failure mode with its own diagnosis. Our Walkthrough troubleshooting guide covers it. Preview and Walkthrough are two sides of the same verification flow, so it's worth keeping both playbooks in mind together.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Agents & Manager2026-05-30
When the Antigravity Agent Says 'command not found' for node or python: Causes and Fixes
It works in your own terminal, but the Antigravity agent hits command not found. Starting from how PATH inheritance works, here are concrete fixes for nvm, pyenv, Homebrew, and WSL setups—plus how to confirm the fix actually took.
Agents & Manager2026-05-26
Why Antigravity's Browser Sub-Agent Reads SPAs as Empty Pages — and Three Wait Strategies That Stuck for Me
When you hand an SPA dashboard to Antigravity's Browser Sub-Agent, get_page_text often returns before the real content is rendered, and the agent reports an empty page. Here is how I diagnose the symptom and the three wait strategies that have stabilized my routine.
Agents & Manager2026-05-09
Why Antigravity Agents Can't Read Your .env File — Three Propagation Paths to Check First
When an Antigravity agent fails with Missing API_KEY but the same build works in your terminal, the cause is one of three env propagation paths. Diagnose each.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →