backendUrl defaults to root-relative, breaking deployments behind a path-prefixing reverse proxy
- Dominant language
- TypeScript
- Stars
- 1k
- Forks
- 267
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 9
Description
## Description
`URLUtil.getApiServerBaseUrl()` (`src/utils/url-util.ts`) returns `runtimeConfig.backendUrl || ''`. When no `backendUrl` is configured, the app falls back to root-relative API calls (e.g. `GET /list-apps`).
This breaks any deployment where the built `adk-web` bundle is served behind a path-prefixing reverse proxy that strips its prefix before forwarding to the backend — e.g. a proxy routing `/agents/my-agent/* -> container` (prefix stripped on the way in). The dev-ui itself loads fine at `/agents/my-agent/dev-ui/`, but its API calls go out root-relative to `/list-apps`, which the proxy has no route for → 404.
`runtime-config.json` is meant to be customized via `set-backend.js`, but that's a build-time script (`npm run serve --backend=...`) run against the *source* before `ng build`. Backends that embed an already-built `adk-web` bundle as a dependency artifact (e.g. `adk-java`'s `AdkWebServer`, which serves `classpath:/browser/**` straight out of the `google-adk-dev` jar) have no build step to run this against and can't easily rewrite a file sealed inside a jar at runtime. So today there's no way for such a backend to get a correct `backendUrl` without patching the frontend itself.
This also affects `getBaseUrlWithoutPath()`, which hardcodes `origin + '/dev-ui/'` and drops any proxy prefix the same way (used as the OAuth `redirectUri`).
## Proposed fix
When `runtimeConfig.backendUrl` isn't set, derive a same-origin default from `window.location` instead of defaulting to root-relative — specifically, preserve whatever path prefix the app was itself loaded under (i.e. strip the `/dev-ui...` suffix off `location.pathname` to recover the mount root, then default `backendUrl` to `origin + mountRoot`). This makes the bundle work behind any path-prefixing reverse proxy out of the box, for any backend embedding it, with no change needed on the backend side — while an explicit `runtimeConfig.backendUrl` (e.g. from `set-backend.js` in local dev) still takes precedence.
I have a fix + tests ready and will open a PR referencing this issue.
Contributor guide
Research direction
Start with URLUtil.getApiServerBaseUrl() and getBaseUrlWithoutPath() in src/utils/url-util.ts. Trace how runtimeConfig.backendUrl and window.location are used, then verify that an explicit backendUrl still wins and that the derived URL preserves the app's mount prefix. Run the existing URL-related tests and add coverage for prefixed deployments and OAuth redirect URLs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100