Skip to content

fix(devframe): advertise a dialable origin when bound to a wildcard host#89

Merged
antfu merged 2 commits into
mainfrom
fix/advertise-dialable-host
Jul 14, 2026
Merged

fix(devframe): advertise a dialable origin when bound to a wildcard host#89
antfu merged 2 commits into
mainfrom
fix/advertise-dialable-host

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Problem

Running a devframe dev server with --host 0.0.0.0 (as needed to reach a preview from outside the machine/container) prints and opens http://0.0.0.0:<port>. A browser can't meaningfully connect to 0.0.0.0 — it's a bind-all address, not a routable host — so the SPA loads at that origin and its same-origin RPC socket fails:

WebSocket connection to 'ws://0.0.0.0:9710/__devframe_ws?...' failed

The WS descriptor is correctly same-origin/relative; the root cause is that the server advertises the wildcard bind host verbatim as its origin.

Fix

Map wildcard (0.0.0.0, ::, empty) and loopback (127.0.0.1) bind hosts to a dialable localhost when advertising a URL — the ready banner, browser-open target, dock/absolute origins, and the baked WS endpoint — while the socket still binds to the wildcard host and stays reachable on every interface. This mirrors how Vite reports its Local: URL under --host 0.0.0.0.

  • toDialableHost / formatHostForUrl added to node/utils.ts; normalizeHttpServerUrl now handles wildcard hosts.
  • startHttpAndWs builds origin and the internal wsUrl through these helpers.
  • createDevServer advertises the dialable origin for resolveOrigin().

Verification

Unit tests for the host mapping plus an integration test that binds createDevServer to 0.0.0.0 and asserts the advertised origin is http://localhost:<port> and reachable. eslint, tsc --noEmit, and the affected vitest suites pass.

This PR was created with the help of an agent.

Binding the dev server to `0.0.0.0` (or `::`) makes it reachable on every
interface, but that address isn't dialable from a browser — opening the
printed `http://0.0.0.0:<port>` URL yields a page whose same-origin RPC
WebSocket (`ws://0.0.0.0:<port>/__devframe_ws`) fails to connect.

Map wildcard and loopback bind hosts to `localhost` when advertising the
origin (ready banner, browser-open, dock/absolute URLs) and the baked WS
endpoint, while still binding the socket to the wildcard host. This mirrors
how Vite reports a `Local:` URL under `--host 0.0.0.0`.
@netlify

netlify Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit 7870fb4
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a55eceb8a2c1d000804a1d4
😎 Deploy Preview https://deploy-preview-89--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

The dialable-origin normalization in devframe/node/utils now also maps
127.0.0.1 to localhost when formatting the WS endpoint URL advertised
by startHttpAndWs. Update the hub context test to match, and refresh
the devframe/node tsnapi export snapshots for the new
formatHostForUrl/toDialableHost exports.
@antfu antfu merged commit bdd3aa9 into main Jul 14, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants