mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-02 02:15:34 +08:00
fix: keep root deployments from inheriting asset basenames
Router basename detection must support root hosting and path-prefix hosting at runtime. The icon fallback used /icons/icon-192x192.png as a basename on root deployments. After login, React Router mounted at /icons while the current URL was /. That mismatch made authenticated root deployments render a blank page. Strip known asset directories even when they are the only path segment. Root icon URLs now keep basename ''. Prefixed /ai/icons/... URLs still resolve to /ai.
This commit is contained in:
26
src/App.tsx
26
src/App.tsx
@@ -1,5 +1,6 @@
|
||||
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
|
||||
import { ThemeProvider } from './contexts/ThemeContext';
|
||||
import { AuthProvider, ProtectedRoute } from './components/auth';
|
||||
import { TaskMasterProvider } from './contexts/TaskMasterContext';
|
||||
@@ -9,12 +10,26 @@ import { PluginsProvider } from './contexts/PluginsContext';
|
||||
import AppContent from './components/app/AppContent';
|
||||
import i18n from './i18n/config.js';
|
||||
|
||||
const DEPLOYMENT_ASSET_DIRECTORIES = new Set(['assets', 'static', 'icons', 'images']);
|
||||
|
||||
/**
|
||||
* Detect the router basename from explicit runtime config or deployment hints.
|
||||
*
|
||||
* CloudCLI can be served from a path prefix by a reverse proxy, for example:
|
||||
* /ai/manifest.json
|
||||
* /ai/assets/index-abc123.js
|
||||
* /ai/icons/icon-192x192.png
|
||||
*
|
||||
* React Router needs that prefix as its basename, but the packaged app should
|
||||
* also keep working when served directly from the domain root. The direct-root
|
||||
* case is easy to misread because asset URLs such as /icons/icon-192x192.png
|
||||
* contain a directory even though there is no application basename.
|
||||
*/
|
||||
function detectRouterBasename() {
|
||||
const explicitBasename = typeof window !== 'undefined' ? window.__ROUTER_BASENAME__ || '' : '';
|
||||
if (explicitBasename) {
|
||||
// Keep the deployment escape hatch authoritative. A trailing slash is
|
||||
// harmless for humans but React Router expects a normalized basename.
|
||||
return explicitBasename.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
@@ -58,9 +73,18 @@ function detectRouterBasename() {
|
||||
const match = candidate.kind === 'manifest' ? manifestMatch : iconMatch;
|
||||
if (match?.[1]) {
|
||||
const segments = match[1].split('/').filter(Boolean);
|
||||
while (segments.length > 1 && ['assets', 'static', 'icons', 'images'].includes(segments[segments.length - 1])) {
|
||||
|
||||
// Strip directories that describe where static files live, not where
|
||||
// the app is mounted. This must also run for a single segment:
|
||||
// /icons/icon-192x192.png -> ''
|
||||
// /ai/icons/icon-192x192.png -> '/ai'
|
||||
// The previous implementation only stripped while more than one
|
||||
// segment remained, which incorrectly turned root deployments into a
|
||||
// Router basename of /icons and caused a blank page after login.
|
||||
while (segments.length > 0 && DEPLOYMENT_ASSET_DIRECTORIES.has(segments[segments.length - 1])) {
|
||||
segments.pop();
|
||||
}
|
||||
|
||||
normalized = segments.length > 0 ? `/${segments.join('/')}` : '';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user