[Refactor] UI - API Reference: Migrate to path-based routing

Move the API Reference page from query-param routing (?page=api_ref) to
Next.js path-based routing (/ui/api-reference). Add a LEGACY_REDIRECTS
map in the root page.tsx so users with old bookmarks are seamlessly
redirected. Future page migrations only need one new map entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yuneng-jiang
2026-03-19 12:57:17 -07:00
co-authored by Claude Opus 4.6
parent b13ba1ddcc
commit 519afa494c
6 changed files with 44 additions and 16 deletions
@@ -1,16 +1,10 @@
"use client";
import APIReferenceView from "@/app/(dashboard)/api-reference/APIReferenceView";
import { useState } from "react";
interface ProxySettings {
PROXY_BASE_URL: string;
PROXY_LOGOUT_URL: string;
LITELLM_UI_API_DOC_BASE_URL?: string | null;
}
import useProxySettings from "@/app/(dashboard)/hooks/proxySettings/useProxySettings";
const APIReferencePage = () => {
const [proxySettings, setProxySettings] = useState<ProxySettings>({ PROXY_BASE_URL: "", PROXY_LOGOUT_URL: "" });
const proxySettings = useProxySettings();
return <APIReferenceView proxySettings={proxySettings} />;
};
@@ -195,7 +195,7 @@ const menuItems: MenuItemCfg[] = [
icon: <UserOutlined style={{ fontSize: 18 }} />,
roles: all_admin_roles,
},
{ key: "14", page: "api_ref", label: "API Reference", icon: <ApiOutlined style={{ fontSize: 18 }} /> },
{ key: "14", page: "api-reference", label: "API Reference", icon: <ApiOutlined style={{ fontSize: 18 }} /> },
{
key: "16",
page: "model-hub-table",
@@ -0,0 +1,20 @@
import { useState, useEffect } from "react";
import { fetchProxySettings } from "@/utils/proxyUtils";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
export default function useProxySettings() {
const { accessToken } = useAuthorized();
const [proxySettings, setProxySettings] = useState({
PROXY_BASE_URL: "",
PROXY_LOGOUT_URL: "",
});
useEffect(() => {
if (!accessToken) return;
fetchProxySettings(accessToken).then((settings) => {
if (settings) setProxySettings(settings);
});
}, [accessToken]);
return proxySettings;
}
+18 -4
View File
@@ -1,6 +1,5 @@
"use client";
import APIReferenceView from "@/app/(dashboard)/api-reference/APIReferenceView";
import SidebarProvider from "@/app/(dashboard)/components/SidebarProvider";
import OldModelDashboard from "@/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView";
import PlaygroundPage from "@/app/(dashboard)/playground/page";
@@ -48,7 +47,7 @@ import { buildLoginUrlWithReturn, consumeReturnUrl, normalizeUrlForCompare, stor
import { formatUserRole, isAdminRole } from "@/utils/roles";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { jwtDecode } from "jwt-decode";
import { useSearchParams } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { Suspense, useEffect, useMemo, useRef, useState } from "react";
import { ConfigProvider, theme } from "antd";
@@ -75,6 +74,15 @@ interface ProxySettings {
LITELLM_UI_API_DOC_BASE_URL?: string | null;
}
/**
* Map of legacy query-param page keys → new path-based route segments.
* When a user visits ?page=<key>, they are redirected to /ui/<value>.
* Add entries here as pages are migrated from the if/else chain to path-based routes.
*/
const LEGACY_REDIRECTS: Record<string, string> = {
api_ref: "api-reference",
};
function CreateKeyPageContent() {
const [userRole, setUserRole] = useState("");
const [premiumUser, setPremiumUser] = useState(false);
@@ -90,6 +98,7 @@ function CreateKeyPageContent() {
});
const [showSSOBanner, setShowSSOBanner] = useState<boolean>(true);
const router = useRouter();
const searchParams = useSearchParams()!;
const [modelData, setModelData] = useState<any>({ data: [] });
const [token, setToken] = useState<string | null>(null);
@@ -431,6 +440,13 @@ function CreateKeyPageContent() {
return <LoadingScreen />;
}
// Redirect legacy query-param pages to their new path-based routes
if (page in LEGACY_REDIRECTS) {
const base = (proxyBaseUrl || "") + "/ui";
router.replace(`${base}/${LEGACY_REDIRECTS[page]}`);
return <LoadingScreen />;
}
return (
<Suspense fallback={<LoadingScreen />}>
<ConfigProvider theme={{
@@ -536,8 +552,6 @@ function CreateKeyPageContent() {
<AdminPanel
proxySettings={proxySettings}
/>
) : page == "api_ref" ? (
<APIReferenceView proxySettings={proxySettings} />
) : page == "logging-and-alerts" ? (
<Settings userID={userID} userRole={userRole} accessToken={accessToken} premiumUser={premiumUser} />
) : page == "budgets" ? (
@@ -231,8 +231,8 @@ const menuGroups: MenuGroup[] = [
groupLabel: "DEVELOPER TOOLS",
items: [
{
key: "api_ref",
page: "api_ref",
key: "api-reference",
page: "api-reference",
label: "API Reference",
icon: <ApiOutlined />,
},
@@ -24,7 +24,7 @@ export const pageDescriptions: Record<string, string> = {
projects: "Manage projects within teams",
"access-groups": "Manage access groups for role-based permissions",
budgets: "Set and monitor spending budgets",
api_ref: "Browse API documentation and endpoints",
"api-reference": "Browse API documentation and endpoints",
"model-hub-table": "Explore available AI models and providers",
"learning-resources": "Access tutorials and documentation",
caching: "Configure response caching settings",