[FEATURE] Preview tool blocks *.localhost subdomains; breaks multi-tenant Next.js dev
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
The Preview tool only allows the literal localhost host. Any subdomain — e.g. acme.localhost:3000 or tenant.localhost:3000 — is rejected with a toast:
"Link to acme.localhost was blocked. Preview only supports localhost URLs."
This breaks Preview-driven verification for any dev server that uses subdomain-based routing, which is the standard pattern for multi-tenant web apps. Today the agent can verify unscoped routes at localhost:3000 but has to defer to me opening a real browser for anything tenant-scoped — defeating much of the point of having Preview at all.
Note: *.localhost is reserved by RFC 6761 §6.3 for loopback. Browsers and resolvers already treat *.localhost identically to localhost (both resolve to 127.0.0.1), so allowing it expands no network surface.
Proposed Solution
Relax the Preview host allowlist to accept *.localhost:
- const isAllowed = (url) => url.host === 'localhost';
+ const isAllowed = (url) =>
+ url.host === 'localhost' || url.host.endsWith('.localhost');
After the change:
preview_startand navigation tools accept*.localhosthosts- Existing
localhostbehavior is unchanged - The block toast no longer fires for
*.localhost
Optionally extend to common dev-loopback aliases (lvh.me, localtest.me) for the same reason — *.localhost alone covers the spec-correct case and is the highest-value win.
Alternative Solutions
- Manually open a real browser for subdomain-routed flows. Works, but defeats agent-driven verification — every UI change becomes human-in-the-loop.
- Add dev-only path-prefix routes (e.g.
/_t/acme/...mirroringacme.localhost/...) to sidestep the subdomain. Non-trivial middleware refactor for Preview ergonomics; not worth the complexity in a real codebase. - Use
127.0.0.1or tunneled URLs instead. Same block applies — Preview only accepts literallocalhost.
Currently working around it by accepting that tenant-scoped UI changes cannot be fully verified by the agent.
Priority
Medium - Would be very helpful
Feature Category
Developer tools/SDK
Use Case Example
- I run a Next.js dev server on
localhost:3000with subdomain-based middleware routing. Unscoped pages serve fromlocalhost:3000; tenant pages serve from<tenant>.localhost:3000. - I ask Claude Code to make a change to the tenant dashboard.
- The agent edits the code and calls
preview_start. The server boots fine. - The agent tries to navigate Preview to
http://acme.localhost:3000/dashboardto verify. - Preview blocks the navigation. The agent reports it can't verify in-browser and asks me to check manually.
- I open Chrome, page works as expected, I tell the agent "looks good." Verification is now human-in-the-loop instead of agent-driven.
With *.localhost allowed, step 5 succeeds — the agent verifies and screenshots the result without my involvement.
Additional Context
- Exact toast text: "Link to <subdomain>.localhost was blocked. Preview only supports localhost URLs."
- Reference: RFC 6761 §6.3 — Domain Name Reservations:
localhost. - The same restriction also blocks tunneled URLs (Cloudflare Tunnel, ngrok). Trust model is different there, so this request is specifically scoped to
*.localhost— it's spec-reserved loopback.
Acceptance criteria:
- [ ]
preview_*tools accept*.localhosthosts and forward through to loopback - [ ] The block toast no longer fires for
*.localhost - [ ] Existing
localhostbehavior unchanged
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗