diff --git a/ui/litellm-dashboard/src/components/navbar.test.tsx b/ui/litellm-dashboard/src/components/navbar.test.tsx
index 9d80a89f83e..99d239d2956 100644
--- a/ui/litellm-dashboard/src/components/navbar.test.tsx
+++ b/ui/litellm-dashboard/src/components/navbar.test.tsx
@@ -261,6 +261,43 @@ describe("Navbar", () => {
mockUseThemeImpl = () => ({ logoUrl: null });
});
+ it("should use the dark logo for the dark variant when one is configured", () => {
+ // Regression test for #46316: the Connect/Chat navbar used the light
+ // logo for both variants, so UI_LOGO_PATH_DARK never showed there.
+ mockUseThemeImpl = () => ({
+ logoUrl: "https://example.com/custom-logo.png",
+ logoUrlDark: "https://example.com/custom-logo-dark.png",
+ });
+
+ renderWithProviders();
+
+ const logoImg = screen.getByAltText("LiteLLM Brand");
+ expect(logoImg).toHaveAttribute("src", "https://example.com/custom-logo.png");
+ const darkLogoImg = Array.from(document.querySelectorAll("img")).find(
+ (img) => img.getAttribute("aria-hidden") === "true"
+ );
+ expect(darkLogoImg).toBeDefined();
+ expect(darkLogoImg).toHaveAttribute("src", "https://example.com/custom-logo-dark.png");
+
+ // Reset mock
+ mockUseThemeImpl = () => ({ logoUrl: null });
+ });
+
+ it("should fall back to the light logo for the dark variant when no dark logo is configured", () => {
+ mockUseThemeImpl = () => ({ logoUrl: "https://example.com/custom-logo.png" });
+
+ renderWithProviders();
+
+ const darkLogoImg = Array.from(document.querySelectorAll("img")).find(
+ (img) => img.getAttribute("aria-hidden") === "true"
+ );
+ expect(darkLogoImg).toBeDefined();
+ expect(darkLogoImg).toHaveAttribute("src", "https://example.com/custom-logo.png");
+
+ // Reset mock
+ mockUseThemeImpl = () => ({ logoUrl: null });
+ });
+
it("should hide user dropdown and notifications on public pages", () => {
const publicPageProps = { ...defaultProps, isPublicPage: true };
renderWithProviders();
diff --git a/ui/litellm-dashboard/src/components/navbar.tsx b/ui/litellm-dashboard/src/components/navbar.tsx
index 8bc9b06969e..04401532527 100644
--- a/ui/litellm-dashboard/src/components/navbar.tsx
+++ b/ui/litellm-dashboard/src/components/navbar.tsx
@@ -37,7 +37,7 @@ const Navbar: React.FC = ({
onToggleSidebar,
}) => {
const baseUrl = getProxyBaseUrl();
- const { logoUrl } = useTheme();
+ const { logoUrl, logoUrlDark } = useTheme();
const { data: healthData } = useHealthReadinessDetails(accessToken);
const version = healthData?.litellm_version;
const disableBouncingIcon = useDisableBouncingIcon();
@@ -45,8 +45,12 @@ const Navbar: React.FC = ({
const { isControlPlane, selectedWorker } = useWorker();
const showWorkerSwitch = isControlPlane && selectedWorker !== null;
+ // Same precedence as the leftnav: an explicit dark logo wins, then the
+ // light logo, then the server default (which honors UI_LOGO_PATH_DARK via
+ // ?theme=dark). Using logoUrl for the dark variant silently dropped the
+ // dark logo on the Connect/Chat pages (#46316).
const imageUrl = logoUrl || `${baseUrl}/get_image`;
- const darkImageUrl = logoUrl || `${baseUrl}/get_image?theme=dark`;
+ const darkImageUrl = logoUrlDark || logoUrl || `${baseUrl}/get_image?theme=dark`;
const handleLogout = useLogout(accessToken);