google / google/adk-web

backendUrl defaults to root-relative, breaking deployments behind a path-prefixing reverse proxy

Open
#515 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.