Skip to content

Commit cc94fb8

Browse files
committed
added base URL helpers
1 parent 051c9a7 commit cc94fb8

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

ui/litellm-dashboard/src/app/(dashboard)/components/Sidebar2.tsx

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ interface MenuItem {
4444
icon?: React.ReactNode;
4545
}
4646

47+
/** ---- BASE URL HELPERS (shared pattern across files) ---- */
48+
function normalizeBasePrefix(raw: string | undefined | null): string {
49+
const trimmed = (raw ?? "").trim();
50+
if (!trimmed) return ""; // no base
51+
// strip leading/trailing slashes then rebuild as "/segment/"
52+
const core = trimmed.replace(/^\/+/, "").replace(/\/+$/, "");
53+
return core ? `/${core}/` : "/";
54+
}
55+
const BASE_PREFIX = normalizeBasePrefix(process.env.NEXT_PUBLIC_BASE_URL);
56+
/** Builds an app-relative path under the configured base prefix. */
57+
function withBase(path: string): string {
58+
// Accepts paths like "/virtual-keys" or "/?page=..." and prefixes with BASE_PREFIX when present.
59+
const body = path.startsWith("/") ? path.slice(1) : path;
60+
const combined = `${BASE_PREFIX}${body}`;
61+
return combined.startsWith("/") ? combined : `/${combined}`;
62+
}
63+
/** -------------------------------------------------------- */
64+
4765
const Sidebar2: React.FC<SidebarProps> = ({
4866
accessToken,
4967
setPage,
@@ -229,7 +247,7 @@ const Sidebar2: React.FC<SidebarProps> = ({
229247
const pushToRootWithPage = (page: string, useReplace = false) => {
230248
const params = new URLSearchParams();
231249
params.set("page", page);
232-
const url = `/?${params.toString()}`;
250+
const url = withBase(`/?${params.toString()}`);
233251
if (useReplace) {
234252
router.replace(url);
235253
} else {
@@ -242,8 +260,8 @@ const Sidebar2: React.FC<SidebarProps> = ({
242260
// Special-case: Virtual Keys target
243261
if (page === "api-keys") {
244262
if (refactoredUIFlag) {
245-
// Go to the dedicated /virtual-keys page
246-
router.push("/virtual-keys");
263+
// Go to the dedicated /virtual-keys page (always under base)
264+
router.push(withBase("/virtual-keys"));
247265
return; // do not call setPage here (parity with previous behavior)
248266
}
249267
// Legacy behavior
@@ -255,8 +273,8 @@ const Sidebar2: React.FC<SidebarProps> = ({
255273
// All other pages
256274
if (refactoredUIFlag) {
257275
// If currently on /virtual-keys, REPLACE it with /?page=...
258-
const onVirtualKeys = pathname?.startsWith("/virtual-keys");
259-
pushToRootWithPage(page, onVirtualKeys);
276+
const onVirtualKeys = pathname?.startsWith(withBase("/virtual-keys"));
277+
pushToRootWithPage(page, !!onVirtualKeys);
260278
} else {
261279
pushToRootWithPage(page);
262280
}

ui/litellm-dashboard/src/app/(dashboard)/layout.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ import Sidebar2 from "@/app/(dashboard)/components/Sidebar2";
77
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
88
import { useRouter, useSearchParams } from "next/navigation";
99

10+
/** ---- BASE URL HELPERS ---- */
11+
function normalizeBasePrefix(raw: string | undefined | null): string {
12+
const trimmed = (raw ?? "").trim();
13+
if (!trimmed) return "";
14+
const core = trimmed.replace(/^\/+/, "").replace(/\/+$/, "");
15+
return core ? `/${core}/` : "/";
16+
}
17+
const BASE_PREFIX = normalizeBasePrefix(process.env.NEXT_PUBLIC_BASE_URL);
18+
function withBase(path: string): string {
19+
const body = path.startsWith("/") ? path.slice(1) : path;
20+
const combined = `${BASE_PREFIX}${body}`;
21+
return combined.startsWith("/") ? combined : `/${combined}`;
22+
}
23+
/** -------------------------------- */
24+
1025
export default function Layout({ children }: { children: React.ReactNode }) {
1126
const router = useRouter();
1227
const searchParams = useSearchParams();
@@ -19,7 +34,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
1934
const updatePage = (newPage: string) => {
2035
const newSearchParams = new URLSearchParams(searchParams);
2136
newSearchParams.set("page", newPage);
22-
router.push(`/?${newSearchParams.toString()}`); // absolute, not relative
37+
router.push(withBase(`/?${newSearchParams.toString()}`)); // always under BASE
2338
setPage(newPage);
2439
};
2540

ui/litellm-dashboard/src/app/page.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
4040
import { cx } from "@/lib/cva.config";
4141
import Sidebar2 from "@/app/(dashboard)/components/Sidebar2";
4242

43+
/** ---- BASE URL HELPERS ---- */
44+
function normalizeBasePrefix(raw: string | undefined | null): string {
45+
const trimmed = (raw ?? "").trim();
46+
if (!trimmed) return "";
47+
const core = trimmed.replace(/^\/+/, "").replace(/\/+$/, "");
48+
return core ? `/${core}/` : "/";
49+
}
50+
const BASE_PREFIX = normalizeBasePrefix(process.env.NEXT_PUBLIC_BASE_URL);
51+
function withBase(path: string): string {
52+
const body = path.startsWith("/") ? path.slice(1) : path;
53+
const combined = `${BASE_PREFIX}${body}`;
54+
return combined.startsWith("/") ? combined : `/${combined}`;
55+
}
56+
/** -------------------------------- */
57+
4358
function getCookie(name: string) {
4459
const cookieValue = document.cookie.split("; ").find((row) => row.startsWith(name + "="));
4560
return cookieValue ? cookieValue.split("=")[1] : null;
@@ -128,11 +143,11 @@ export default function CreateKeyPage() {
128143
setPage(searchParams.get("page") || "api-keys");
129144
}, [searchParams]);
130145

131-
// Custom setPage function that updates URL
146+
// Custom setPage function that updates URL (always under BASE)
132147
const updatePage = (newPage: string) => {
133148
const newSearchParams = new URLSearchParams(searchParams);
134149
newSearchParams.set("page", newPage);
135-
router.push(`/?${newSearchParams.toString()}`); // absolute, not relative
150+
router.push(withBase(`/?${newSearchParams.toString()}`));
136151
setPage(newPage);
137152
};
138153

@@ -160,6 +175,7 @@ export default function CreateKeyPage() {
160175

161176
useEffect(() => {
162177
if (redirectToLogin) {
178+
// This is an external auth route (kept as-is, not app navigation).
163179
window.location.href = (proxyBaseUrl || "") + "/sso/key/generate";
164180
}
165181
}, [redirectToLogin]);

0 commit comments

Comments
 (0)