Skip to content

feat(load-balancer): make the development provider URL configurable - #3232

Merged
forgetso merged 4 commits into
mainfrom
feat/dev-provider-url-env-var
Sep 10, 2026
Merged

forgetso merged 4 commits into
mainfrom
feat/dev-provider-url-env-var

Conversation

@forgetso

Copy link
Copy Markdown
Member

What was annoying

In development the widget looks for its provider at a hardcoded https://localhost:9229.

That is right when the page and the provider are on the same machine, and wrong the moment they are not. A phone or an iOS simulator loading the demo over the LAN resolves localhost to itself, so the widget never reaches the provider. The failure surfaces as "Site key not registered", which reads like a configuration problem with the site key rather than what it is — the request went nowhere.

It cost a while to work out when testing a mobile-only bug on a real device, because nothing in the error points at the provider URL.

What changed

PROSOPO_PROVIDER_URL_DEVELOPMENT now overrides it:

PROSOPO_PROVIDER_URL_DEVELOPMENT="https://192.0.2.10:9229" npm run start:bundle

Unset, it still falls back to https://localhost:9229, so existing setups are unaffected. Staging and production resolve through their DNS-routed endpoints and ignore it entirely.

The URL was hardcoded in two places — the DNS endpoint map in providers.ts and the single-provider dev list in balancer.ts — and both now read the same resolver.

Two details worth a look in review

  • The override is read as a static process.env.X access, because the frontend build substitutes that exact expression for a literal. A computed lookup (process.env[key]) would not be matched and would silently never work in the browser. For the same reason there is no typeof process guard: in a browser bundle the expression is already a string by the time it runs, and guarding on a process that does not exist there would throw the value away.
  • The endpoint map is now built per call rather than once at module load, so an override set after the module is first imported is still picked up.

Effect

Development only. No change to staging or production behaviour, and no change when the variable is unset.

Test coverage

7 tests: the default, an override, trailing-slash normalisation, empty and whitespace-only values falling back rather than yielding an empty URL, reading the variable, and the unset case.

Also checked end to end against the built package — with the variable set, getRandomActiveProvider("development") and loadBalancer("development") both return the override; without it, both return https://localhost:9229.

Suite: 49 passed, 0 type errors.

🤖 Generated with Claude Code

forgetso and others added 2 commits September 10, 2026 07:53
In development the widget looked for its provider at a hardcoded
https://localhost:9229. That is right when the page and the provider share a
machine and wrong as soon as they do not: a phone or an iOS simulator loading
the demo over the LAN resolves localhost to itself, never reaches the provider,
and reports the site key as unregistered.

PROSOPO_PROVIDER_URL_DEVELOPMENT now overrides it. Unset, it still falls back
to https://localhost:9229, so existing setups are unaffected. Staging and
production resolve through their DNS-routed endpoints and ignore it.

The override is read as a static process.env access so the frontend build can
substitute it for a literal, and the endpoint map is resolved per call rather
than once at module load.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The fixtures used a real LAN address from the machine they were written on.
RFC 5737 reserves 192.0.2.0/24 and 198.51.100.0/24 for exactly this, and they
cannot resolve to anything real.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@forgetso
forgetso enabled auto-merge (squash) September 10, 2026 08:38
@forgetso
forgetso merged commit 0d479f9 into main Sep 10, 2026
14 checks passed
@forgetso
forgetso deleted the feat/dev-provider-url-env-var branch September 10, 2026 08:49
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.

1 participant