From e7590d72fd733b4c883c8432eb1d8e4643c7813f Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:53:48 +0100 Subject: [PATCH] fix: restore Swagger UI on api-docs page - Change Vite proxy pattern from /api to /api/ so /api-docs client route is not captured and proxied to the backend - Fix SwaggerUIBundle init: remove empty presets/layout overrides that crashed the internal persistConfigs function - Use correct CSS import (swagger-ui.css instead of index.css) - Add requestInterceptor to auto-attach JWT token to Try-it-out calls - Add swagger-ui-bundle to optimizeDeps.include for reliable loading - Remove unused swagger-ui-dist.d.ts type declarations Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/pages/Swagger/SwaggerPage.tsx | 22 +++++++++++++++------- ui/src/swagger-ui-dist.d.ts | 9 --------- ui/vite.config.ts | 5 ++++- 3 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 ui/src/swagger-ui-dist.d.ts diff --git a/ui/src/pages/Swagger/SwaggerPage.tsx b/ui/src/pages/Swagger/SwaggerPage.tsx index 537c6edc..5f6d0205 100644 --- a/ui/src/pages/Swagger/SwaggerPage.tsx +++ b/ui/src/pages/Swagger/SwaggerPage.tsx @@ -1,24 +1,32 @@ import { useEffect, useRef } from 'react'; import { config } from '../../config'; +import { useAuthStore } from '../../auth/auth-store'; +import 'swagger-ui-dist/swagger-ui.css'; export default function SwaggerPage() { const containerRef = useRef(null); + const token = useAuthStore((s) => s.accessToken); useEffect(() => { - let cleanup: (() => void) | undefined; + let cancelled = false; - import('swagger-ui-dist/swagger-ui-bundle').then(({ default: SwaggerUIBundle }) => { - if (!containerRef.current) return; + import('swagger-ui-dist/swagger-ui-bundle').then((mod) => { + const SwaggerUIBundle = mod.default || mod; + if (cancelled || !containerRef.current || typeof SwaggerUIBundle !== 'function') return; SwaggerUIBundle({ url: `${config.apiBaseUrl}/api-docs`, domNode: containerRef.current, - presets: [], - layout: 'BaseLayout', + requestInterceptor: (req: { headers: Record }) => { + if (token) { + req.headers['Authorization'] = `Bearer ${token}`; + } + return req; + }, }); }); - return () => cleanup?.(); - }, []); + return () => { cancelled = true; }; + }, [token]); return (
diff --git a/ui/src/swagger-ui-dist.d.ts b/ui/src/swagger-ui-dist.d.ts deleted file mode 100644 index c3b16e3c..00000000 --- a/ui/src/swagger-ui-dist.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module 'swagger-ui-dist' { - export function getAbsoluteFSPath(): string; - export const SwaggerUIBundle: unknown; - export const SwaggerUIStandalonePreset: unknown; -} -declare module 'swagger-ui-dist/swagger-ui-bundle' { - const SwaggerUIBundle: (config: Record) => void; - export default SwaggerUIBundle; -} diff --git a/ui/vite.config.ts b/ui/vite.config.ts index cff36064..4c5e1017 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ plugins: [react()], server: { proxy: { - '/api': { + '/api/': { target: apiTarget, changeOrigin: true, secure: false, @@ -21,6 +21,9 @@ export default defineConfig({ }, }, }, + optimizeDeps: { + include: ['swagger-ui-dist/swagger-ui-bundle'], + }, build: { outDir: 'dist', },