[FEATURE] Support `url` field in `launch.json` for preview feature

Status Fixed / completed
Maintainer reply None cached
Activity 15 comments · opened Feb 27, 2026 · closed Aug 17, 2026

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

My dev server runs on https and needs to be accessed via a specific URL. This seems to be incompatible with Claude code's "preview" feature which always connects to localhost

Proposed Solution

Support url in the launch.json configuration that the preview feature reads.

Alternative Solutions

_No response_

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

_No response_

Additional Context

_No response_

View original on GitHub ↗

14 Comments

Raymond-Youssef · 5 months ago

+1 on this one

ksweetie · 5 months ago

Another use case for this is subdomains. We rely on http://foobar.localhost, which currently isn't possible.

modularcoder · 5 months ago

+1 on this one

bordeo · 5 months ago

With the advent of portless, this feature is becoming more important.

georg-wolflein · 4 months ago

+1 this is preventing me from switching from Cursor to Claude Code

EyalPerry · 4 months ago

totally important, +1 on the advent of portless

Tilotiti · 4 months ago

+1 Unable to develop a Symfony project without it.

dontfeedthecode · 4 months ago

For the love of God add this feature +1

mochini · 4 months ago

this would be very useful - especially for apps that require https even in development

tomnewton · 4 months ago

Need! Thank you

1vav · 4 months ago

+1 for this. A url field would cover the common case where the preview server is already running (managed by a hook, launchd, or any external process) and preview_start just needs to open the pane against it — no process config, no path resolution needed.

atifgelato · 4 months ago

Same need here — our Angular app uses Keycloak for SSO, so the very first load redirects to an external auth server (auth.ie.test.gelato.tech) before the app renders. Preview blocks it immediately with:

Link to auth.ie.test.gelato.tech was blocked. Preview only supports localhost URLs.

A url field in launch.json (or an external URL allowlist in settings) would solve this. Being able to tell Preview "trust these domains as part of the local dev flow" is the missing piece for any app with an external identity provider.

Related: #27263

chenghan821101 · 3 months ago

Adding a workaround that's been working well for HTML→Vue and Vue→HTML prototype-to-product fidelity smoke testing in our internal Claude Code workflow — sharing in case it helps others hitting the same cross-origin gap.

A path-routing reverse proxy on a single port lets the preview tool bind to one origin while reaching multiple dev servers. preview_eval and preview_inspect then work across both apps because they're same-origin.

Minimal zero-dependency Node implementation:

const http = require('http');
const net = require('net');

const PROXY_PORT = Number(process.env.PORT || 8792);
const PROTO_TARGET = { host: 'localhost', port: 8791 };  // your "A" server
const VUE_TARGET = { host: 'localhost', port: 9100 };    // your "B" server (fallback)

function pickTarget(url) {
  if (url.startsWith('/proto/')) {
    return { target: PROTO_TARGET, rewrittenUrl: url.slice('/proto'.length) || '/' };
  }
  return { target: VUE_TARGET, rewrittenUrl: url };
}

const server = http.createServer((req, res) => {
  const { target, rewrittenUrl } = pickTarget(req.url);
  const proxyReq = http.request({
    host: target.host,
    port: target.port,
    method: req.method,
    path: rewrittenUrl,
    headers: { ...req.headers, host: `${target.host}:${target.port}` },
  }, (proxyRes) => {
    res.writeHead(proxyRes.statusCode, proxyRes.headers);
    proxyRes.pipe(res);
  });
  proxyReq.on('error', (err) => { res.writeHead(502); res.end(err.message); });
  req.pipe(proxyReq);
});

server.on('upgrade', (req, socket, head) => {
  // WebSocket forwarding — defaults to fallback target so Vite HMR works
  const target = req.url.startsWith('/proto/') ? PROTO_TARGET : VUE_TARGET;
  const upstream = net.connect(target.port, target.host, () => {
    const headerLines = Object.entries(req.headers).map(([k, v]) => `${k}: ${v}`).join('\r\n');
    upstream.write(`${req.method} ${req.url} HTTP/${req.httpVersion}\r\n${headerLines}\r\n\r\n`);
    if (head && head.length) upstream.write(head);
    upstream.pipe(socket);
    socket.pipe(upstream);
  });
});

server.listen(PROXY_PORT);

.claude/launch.json entry:

{
  "name": "smoke-proxy (unifies two dev servers)",
  "runtimeExecutable": "node",
  "runtimeArgs": ["path/to/smoke-proxy.js"],
  "port": 8792
}

Usage: preview_start "smoke-proxy ...". Navigate /proto/* for the static app and / (or any path) for the dynamic app. Cross-side window.location.href = '/proto/...' works; preview_eval and preview_inspect see both sides through the unified origin.

Caveats:

  • Doesn't rewrite response body URLs — absolute URLs hardcoded in HTML may need adjustment
  • Same-origin <iframe> wrappers also work for screenshots-only, but Chromium blocks cross-origin DOM access for preview_inspect into the iframe
  • WebSocket forwarding included for Vite HMR; defaults to the fallback target

Not a substitute for the official url / allowedOrigins field this issue requests — that would be the cleaner long-term solution.

timherby · 3 months ago

Running into the same thing. We use subdomains, and I'm looking to switch from Conductor due to the upcoming June 15 billing change Anthropic is imposing. Very disappointed to learn that the Claude Code preview doesn't work for subdomains.

We use 2 local loopback subdomains of our own, so need to be able to allowlist these to custom loopback domains.

Link to local.companydomain.com was blocked. Preview only supports localhost URLs.

🙏 Please listen to the numerous people on this thread and fix this prevalent issue.

Showing cached comments. Read the full discussion on GitHub ↗