feat: add sub-directory deployment support and base path configuration
- Introduced APP_BASE_PATH in .env.example for deployment path configuration.
- Updated server/index.js to handle dynamic base path for routes, WebSocket connections, and static assets.
- Modified React components to utilize BASE_URL for asset paths and router basename.
- Enhanced WebSocket connection handling to respect the base path.
- Adjusted API utility functions to prepend BASE_URL to relative paths.
Summary by CodeRabbit
-
New Features
- App and client now support deployment under a custom base path so routes, assets, WebSocket connections, and injected runtime values work correctly when hosted in a sub-directory.
-
Bug Fixes
- Improved connection handling to avoid attempting WebSocket connections when required credentials are missing and to ensure asset/HTML responses resolve correctly under a base path.
-
Chores
- Added a deployment configuration variable in the environment to specify the application base path.
✏️ Tip: You can customize this high-level summary in your review settings.
Walkthrough
Adds configurable APP_BASE_PATH support: server mounts routes under a router at that base path and injects it into served HTML/manifest; client reads window.APP_BASE_PATH (BASE_URL/ROUTER_BASENAME) to prefix API calls, WebSocket URLs, router basename, and asset imports.
Changes
| Cohort / File(s) | Change Summary |
|---|---|
Environment Configuration \.env.example |
Adds a DEPLOYMENT CONFIGURATION section documenting APP_BASE_PATH and usage guidance for root vs sub-directory deployments. |
Server base-path routing & HTML injection server/index.js |
Introduces APP_BASE_PATH, refactors to use an expressApp and a mounted router at the base path, updates WebSocket setup to be base-path-aware, rewrites served manifest.json/*.html/dist/index.html to inject APP_BASE_PATH and adjust asset/script URLs, and adjusts caching headers for HTML vs static assets. |
Client base discovery & fetch/WebSocket wiring src/utils/api.js, src/utils/websocket.js |
Adds BASE_URL and ROUTER_BASENAME (from window.__APP_BASE_PATH__) exports; authenticatedFetch now merges headers, omits Content-Type for FormData, and prepends BASE_URL to relative URLs. WebSocket URL construction now uses BASE_URL and avoids connecting when required token is missing. |
Router basename usage src/App.jsx |
Imports ROUTER_BASENAME and sets Router basename={ROUTER_BASENAME} to enable client routing under the configured base path. |
Asset path updates in components src/components/ClaudeLogo.jsx, src/components/CursorLogo.jsx |
Replace hardcoded icon paths with ${BASE_URL}/icons/... by importing BASE_URL from src/utils/api.js; remove explicit React import (JSX runtime). |
Sequence Diagram(s)
sequenceDiagram
participant Browser
participant Server
participant expressApp as expressApp
participant router as Router (mounted)
participant Injector as HTML/Manifest Injector
Browser->>Server: GET /myapp/ (or /myapp/index.html)
Server->>expressApp: Accept request
expressApp->>router: Forward to router mounted at APP_BASE_PATH (/myapp)
router->>Injector: Request index/manifest
Injector->>Injector: Rewrite asset URLs, inject window.__APP_BASE_PATH__ = '/myapp'
Injector-->>Browser: Serve HTML/manifest with injected base path
Browser->>Browser: Initialize React app, read window.__APP_BASE_PATH__
Browser->>Server: API request to `${BASE_URL}/user` (via authenticatedFetch)
sequenceDiagram
participant App as React App
participant API as api.js
participant WS as websocket.js
participant Server as Backend (HTTP/WS)
App->>API: Read ROUTER_BASENAME / BASE_URL
App->>App: Router basename={ROUTER_BASENAME}
App->>API: authenticatedFetch('/status')
API->>API: Prepend BASE_URL -> `${BASE_URL}/status`
API->>Server: HTTP request to `${BASE_URL}/status`
App->>WS: useWebSocket()
WS->>Server: Connect to `${BASE_URL}/ws` (with token if required)
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~45 minutes
- Pay special attention to
server/index.js(router mounting, HTML/manifest rewriting, WebSocket path handling, caching headers). - Review
src/utils/api.jsheader merge and relative-URL detection to ensure no double-prefixing or incorrect absolute-URL handling. - Confirm
window.__APP_BASE_PATH__injection timing vs client initialization to avoid race conditions.
Possibly related PRs
- siteboon/claudecodeui#216 — Modifies
src/utils/websocket.jsandserver/index.js; likely related changes to WebSocket URL handling and base-path wiring.
Poem
🐰
I hopped along the filesystem trail,
tucked base paths under my tail,
injected whispers in the page,
so apps can roam from stage to stage.
A little hop, a stable path — deploy without fail!
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title accurately describes the main change: adding support for sub-directory deployments with configurable base paths across server configuration, routing, WebSocket handling, and client-side asset resolution. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.