claudecodeui icon indicating copy to clipboard operation
claudecodeui copied to clipboard

feat: add sub-directory deployment support and base path configuration

Open yingca1 opened this issue 1 month ago • 1 comments

  • 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.

yingca1 avatar Nov 22 '25 22:11 yingca1

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.js header 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.js and server/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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Nov 22 '25 22:11 coderabbitai[bot]