API URLs use absolute paths, breaking subpath reverse proxy setups
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 158
Description
# Some API URLs use absolute paths, breaking subpath reverse proxy setups
## Description
Several places in the frontend construct API URLs as absolute paths (starting with `/`) without going through `ComfyApi.apiURL()`. When ComfyUI is served behind a reverse proxy with a subpath (e.g., JupyterHub at `/proxy/8188/`, nginx with `location /comfyui/`, etc.), the browser resolves these absolute paths to the domain root, bypassing the proxy subpath entirely.
Most of the codebase correctly uses `apiURL()` (which prepends `api_base`), but a few places bypass it and hardcode absolute paths.
## Affected Code
1. **`WidgetSelect`** — image selector thumbnail preview:
```javascript
// Current (broken behind subpath proxy):
return ce(r,e),`/api/view?${r}`
// Should be:
return ce(r,e),`api/view?${r}`
// Or better, use apiURL():
return ce(r,e), api.apiURL(`/api/view?${r}`)
```
2. **`getResourceURL()` in `core` and `load3dService`**:
```javascript
// Current:
return`/view?${[`filename=`+encodeURIComponent(t),`type=`+n,`subfolder=`+...].join("&")}`
// Should use apiURL() or be relative:
return`view?${[...].join("&")}`
```
These are the only patterns that break. All other `/view?` usages in `dialogService`, `GraphView`, etc. correctly go through `B.apiURL()` or `cs.apiURL()` and work fine behind a proxy.
## Steps to Reproduce
1. Set up any reverse proxy that serves ComfyUI under a subpath, for example:
- nginx: `location /comfyui/ { proxy_pass http://localhost:8188/; }`
- JupyterHub: automatic via `/proxy/8188/`
- Traefik: PathPrefix `/comfyui`
2. Access ComfyUI through the proxy (e.g., `https://myhost.com/comfyui/`)
3. Add a "Load Image" node to the workflow
4. Click the image selector dropdown
5. Open browser DevTools → Network tab
## Expected Behavior
Image thumbnails load. API requests go to `https://myhost.com/comfyui/api/view?filename=...&type=input`
## Actual Behavior
All thumbnails are broken (404). API requests go to `https://myhost.com/api/view?filename=...&type=input` — the proxy subpath `/comfyui/` is missing because the frontend uses absolute paths starting with `/`.
## Debug Logs
Browser Network tab:
```
GET https://myhost.com/api/view?filename=example.png&type=input → 404 Not Found
```
The correct URL should be:
```
GET https://myhost.com/comfyui/api/view?filename=example.png&type=input → 200 OK
```
No errors appear in ComfyUI server logs — the requests never reach the backend.
## Suggested Fix
Option A (minimal): Make the affected URLs relative (remove leading `/`):
```javascript
// WidgetSelect:
`api/view?${r}` // instead of `/api/view?${r}`
// getResourceURL:
`view?${[...].join("&")}` // instead of `/view?${[...].join("&")}`
```
Option B (consistent): Route all view URLs through `apiURL()` like the rest of the codebase already does:
```javascript
api.apiURL(`/api/view?${r}`)
```
Option C (comprehensive): Expose a configurable `PUBLIC_PATH` / `base` setting (like Vite's `base` config) that all URL construction respects.
## Environment
- ComfyUI: latest master (commit 822aca19)
- comfyui-frontend-package: 1.45.15
- Proxy: JupyterHub (nginx-based reverse proxy with subpath)
- Browser: Microsoft Edge 149
- OS: Ubuntu (container on Kubernetes)
## Other
This also affects `getResourceURL()` used by 3D model loading (`load3dService`).
Note that most of the frontend already handles this correctly via `apiURL()` — only a few places bypass it. The fix is straightforward and backwards-compatible (relative URLs work identically to absolute ones when accessed directly on localhost).
Contributor guide
Assessment
This issue has not been assessed yet.