Commits
Tarun Sukhani authored f421f532b6f
fix(skel): resolve the frontend's backend port instead of hardcoding 9000 (PF-166)
nuxt-skel hardcoded http://localhost:9000 in three places — the nitro devProxy
target, the SSR routeRules proxy, and the "(port 9000)" text on the index page.
Running Play anywhere else (`play run --http.port=9001`, or http.port= in
conf/application.conf) silently broke every /api/** call from the frontend, with
nothing to indicate why. That bites immediately, since Play's default port is
shared by every Play app on a machine: moving a new app off 9000 to dodge a
collision is exactly what breaks its own frontend. jclaw already carries a
hand-rolled JCLAW_BACKEND_PORT patch for this — a per-app workaround for a skel
defect.
The port is now resolved in nuxt.config.ts, in precedence order:
1. PLAY_BACKEND_PORT — for a `play run --http.port=` CLI override, which never
touches application.conf
2. http.port from the app's own conf/application.conf — set it there once and
both halves of the app agree with no extra step
3. 9000 — Play's default, unchanged
Only unprefixed http.port keys are read: a %prod.http.port belongs to a
different play.id and must not redirect the dev proxy. A missing conf file falls
through silently so a frontend checked out on its own still works. The resolved
value is exposed via runtimeConfig.public.backendPort and rendered by
pages/index.vue, so the scaffold stops printing a port it may not be using.
Deliberately NOT auto-detected by probing for a listening server. Play's default
port is shared across apps, so probing binds to whatever answers — possibly a
different application entirely. That failure mode was observed live during
triage: a stale browser tab belonging to another Play app was polling 9000 and
its requests landed on a freshly scaffolded app that had taken the port. A silent
wrong-backend connection is far harder to diagnose than a refused one. Resolve
the configured port; never guess the running one.
Verified end-to-end on a scaffolded app, backend and frontend as separate
processes, asserting on proxied responses rather than config inspection:
conf http.port=9021, no env -> /api/status via the frontend returned the
app's own JSON; page rendered "(port 9021)"
conf 9099 (dead) + env 9021 -> proxy still reached 9021, 200 — env wins
stock conf, no env -> page rendered "(port 9000)" — no regression
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>